@quantyapp/quanty-mcp-server 1.2.0 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Binary file
@@ -42,6 +42,7 @@ export interface AbcItem {
42
42
  percentage: number;
43
43
  accumulated: number;
44
44
  class: 'A' | 'B' | 'C';
45
+ resourceType: string;
45
46
  }
46
47
  export interface AbcCurveResult {
47
48
  totalValue: number;
@@ -1 +1 @@
1
- {"version":3,"file":"analysisService.d.ts","sourceRoot":"","sources":["../../src/core/analysisService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+CtG;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA0DvG;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAmDrB;AAID,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAClC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,MAAW,EAC5B,eAAe,GAAE,MAAW,GAC7B,OAAO,CAAC,cAAc,CAAC,CAwFzB"}
1
+ {"version":3,"file":"analysisService.d.ts","sourceRoot":"","sources":["../../src/core/analysisService.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAGxC,MAAM,WAAW,aAAa;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA+CtG;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CA0DvG;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CACtC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAmDrB;AAID,MAAM,WAAW,OAAO;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAClC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,MAAW,EAC5B,eAAe,GAAE,MAAW,GAC7B,OAAO,CAAC,cAAc,CAAC,CA0FzB"}
@@ -164,6 +164,7 @@ export async function generateAbcCurve(auth, budgetId, classAThreshold = 80, cla
164
164
  if (error)
165
165
  throw new Error(`Failed to get budget: ${error.message}`);
166
166
  const rows = data?.data?.rows || [];
167
+ const abcClassifications = data?.data?.abcClassifications || {};
167
168
  // Filter only rows with actual values (non-empty rows)
168
169
  const validRows = rows.filter(r => r.description && r.description.trim() !== '' &&
169
170
  r.quantity > 0 && r.unitCost > 0);
@@ -220,7 +221,8 @@ export async function generateAbcCurve(auth, budgetId, classAThreshold = 80, cla
220
221
  total: Math.round(item.total * 100) / 100,
221
222
  percentage: Math.round(percentage * 100) / 100,
222
223
  accumulated: Math.round(accumulated * 100) / 100,
223
- class: itemClass
224
+ class: itemClass,
225
+ resourceType: abcClassifications[item.id] || 'Custo'
224
226
  };
225
227
  });
226
228
  return {
@@ -23,6 +23,8 @@ export interface Budget {
23
23
  rows: BudgetRow[];
24
24
  bdiPrincipal: number;
25
25
  bdiDiferenciado: number;
26
+ bdiItemsPrincipal: any[];
27
+ bdiItemsDiferenciado: any[];
26
28
  }
27
29
  export interface BudgetSummary {
28
30
  id: string;
@@ -128,6 +130,60 @@ export declare function prepareUpdateBdi(budgetId: string, bdiPrincipal?: number
128
130
  * Executes BDI update
129
131
  */
130
132
  export declare function executeUpdateBdi(auth: AuthContext, data: any): Promise<void>;
133
+ export interface BdiItem {
134
+ id?: string;
135
+ description: string;
136
+ percentage: number;
137
+ incidence: string;
138
+ }
139
+ /**
140
+ * Calcula o BDI total baseado nos itens de composição
141
+ * Fórmula: BDI = ((1 + i_custo) / (1 - i_venda) - 1) * 100
142
+ *
143
+ * Onde:
144
+ * - i_custo = soma dos % que incidem sobre o Custo (ex: Administração, Risco)
145
+ * - i_venda = soma dos % que incidem sobre a Venda (ex: ISS, PIS, COFINS, Lucro)
146
+ */
147
+ export declare function calculateBdiTotal(items: BdiItem[]): number;
148
+ /**
149
+ * Prepares adding an item to BDI composition
150
+ */
151
+ export declare function prepareAddBdiItem(budgetId: string, bdiType: 'Principal' | 'Diferenciado', item: BdiItem): {
152
+ action: string;
153
+ preview: string;
154
+ data: any;
155
+ };
156
+ /**
157
+ * Executes adding item to BDI composition
158
+ * ATUALIZADO: Recalcula automaticamente o BDI total
159
+ */
160
+ export declare function executeAddBdiItem(auth: AuthContext, data: any): Promise<void>;
161
+ /**
162
+ * Prepares editing an existing BDI item
163
+ */
164
+ export declare function prepareEditBdiItem(budgetId: string, bdiType: 'Principal' | 'Diferenciado', itemId: string, updates: Partial<BdiItem>): {
165
+ action: string;
166
+ preview: string;
167
+ data: any;
168
+ };
169
+ /**
170
+ * Executes editing BDI item
171
+ * ATUALIZADO: Recalcula automaticamente o BDI total
172
+ */
173
+ export declare function executeEditBdiItem(auth: AuthContext, data: any): Promise<void>;
174
+ /**
175
+ * Prepares removing an item from BDI composition
176
+ */
177
+ export declare function prepareRemoveBdiItem(budgetId: string, bdiType: 'Principal' | 'Diferenciado', itemId: string, itemDescription: string): {
178
+ action: string;
179
+ preview: string;
180
+ data: any;
181
+ };
182
+ /**
183
+ * Executes removing BDI item
184
+ * ATUALIZADO: Recalcula automaticamente o BDI total
185
+ */
186
+ export declare function executeRemoveBdiItem(auth: AuthContext, data: any): Promise<void>;
131
187
  /**
132
188
  * Prepares editing an existing item
133
189
  */
@@ -278,4 +334,114 @@ export declare function prepareConvertToCost(budgetId: string, itemId: string, i
278
334
  * Executes converting a composition back to cost
279
335
  */
280
336
  export declare function executeConvertToCost(auth: AuthContext, data: any): Promise<void>;
337
+ export interface Tag {
338
+ id: string;
339
+ budget_id: string;
340
+ name: string;
341
+ created_at: string;
342
+ }
343
+ /**
344
+ * Lists all tags for a specific budget
345
+ */
346
+ export declare function getTagsForBudget(budgetId: string): Promise<Tag[]>;
347
+ /**
348
+ * Prepares adding a tag to a budget
349
+ */
350
+ export declare function prepareAddTag(budgetId: string, name: string): {
351
+ action: string;
352
+ preview: string;
353
+ data: any;
354
+ };
355
+ /**
356
+ * Executes adding a tag
357
+ */
358
+ export declare function executeAddTag(auth: AuthContext, data: any): Promise<Tag>;
359
+ /**
360
+ * Prepares editing a tag
361
+ */
362
+ export declare function prepareEditTag(tagId: string, newName: string, currentName: string): {
363
+ action: string;
364
+ preview: string;
365
+ data: any;
366
+ };
367
+ /**
368
+ * Executes editing a tag
369
+ */
370
+ export declare function executeEditTag(auth: AuthContext, data: any): Promise<void>;
371
+ /**
372
+ * Prepares removing a tag
373
+ */
374
+ export declare function prepareRemoveTag(tagId: string, tagName: string): {
375
+ action: string;
376
+ preview: string;
377
+ data: any;
378
+ };
379
+ /**
380
+ * Executes removing a tag
381
+ */
382
+ export declare function executeRemoveTag(auth: AuthContext, data: any): Promise<void>;
383
+ export interface Project {
384
+ id: string;
385
+ code?: string;
386
+ name: string;
387
+ description?: string;
388
+ created_at: string;
389
+ updated_at?: string;
390
+ }
391
+ /**
392
+ * Lists all projects for the authenticated user's tenant
393
+ */
394
+ export declare function getProjects(auth: AuthContext): Promise<Project[]>;
395
+ /**
396
+ * Prepares creating a new project
397
+ */
398
+ export declare function prepareCreateProject(name: string, description?: string, code?: string): {
399
+ action: string;
400
+ preview: string;
401
+ data: any;
402
+ };
403
+ /**
404
+ * Executes creating a project
405
+ */
406
+ export declare function executeCreateProject(auth: AuthContext, data: any): Promise<Project>;
407
+ /**
408
+ * Prepares editing a project
409
+ */
410
+ export declare function prepareEditProject(projectId: string, updates: {
411
+ name?: string;
412
+ description?: string;
413
+ code?: string;
414
+ }, currentName: string): {
415
+ action: string;
416
+ preview: string;
417
+ data: any;
418
+ };
419
+ /**
420
+ * Executes editing a project
421
+ */
422
+ export declare function executeEditProject(auth: AuthContext, data: any): Promise<void>;
423
+ /**
424
+ * Prepares deleting a project (soft delete)
425
+ */
426
+ export declare function prepareDeleteProject(projectId: string, projectName: string): {
427
+ action: string;
428
+ preview: string;
429
+ data: any;
430
+ };
431
+ /**
432
+ * Executes deleting a project (soft delete)
433
+ */
434
+ export declare function executeDeleteProject(auth: AuthContext, data: any): Promise<void>;
435
+ /**
436
+ * Prepares linking a budget to a project
437
+ */
438
+ export declare function prepareLinkBudgetToProject(budgetId: string, projectId: string | null, budgetTitle: string, projectName: string | null): {
439
+ action: string;
440
+ preview: string;
441
+ data: any;
442
+ };
443
+ /**
444
+ * Executes linking a budget to a project
445
+ */
446
+ export declare function executeLinkBudgetToProject(auth: AuthContext, data: any): Promise<void>;
281
447
  //# sourceMappingURL=budgetService.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"budgetService.d.ts","sourceRoot":"","sources":["../../src/core/budgetService.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"budgetService.d.ts","sourceRoot":"","sources":["../../src/core/budgetService.ts"],"names":[],"mappings":"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"}
@@ -54,7 +54,9 @@ export async function getBudget(auth, budgetId) {
54
54
  projectId: data.project_id,
55
55
  rows: data.data?.rows || [],
56
56
  bdiPrincipal: data.data?.bdiPrincipal || 0,
57
- bdiDiferenciado: data.data?.bdiDiferenciado || 0
57
+ bdiDiferenciado: data.data?.bdiDiferenciado || 0,
58
+ bdiItemsPrincipal: data.data?.bdiItemsPrincipal || [],
59
+ bdiItemsDiferenciado: data.data?.bdiItemsDiferenciado || []
58
60
  };
59
61
  }
60
62
  /**
@@ -89,6 +91,9 @@ export function prepareCreateBudget(auth, title) {
89
91
  */
90
92
  export async function executeCreateBudget(auth, data) {
91
93
  const now = new Date().toISOString();
94
+ // Gera a data base padrão no formato MM/AAAA
95
+ const nowDate = new Date();
96
+ const defaultBaseDate = `${String(nowDate.getMonth() + 1).padStart(2, '0')}/${nowDate.getFullYear()}`;
92
97
  const budgetData = {
93
98
  title: data.title,
94
99
  tenant_id: data.tenantId,
@@ -100,6 +105,7 @@ export async function executeCreateBudget(auth, data) {
100
105
  deleted: false,
101
106
  data: {
102
107
  title: data.title,
108
+ baseDate: defaultBaseDate, // Data Base padrão = data de criação
103
109
  // Cria 50 linhas vazias
104
110
  rows: Array.from({ length: 50 }, () => ({
105
111
  id: crypto.randomUUID(),
@@ -340,6 +346,169 @@ export async function executeUpdateBdi(auth, data) {
340
346
  if (error)
341
347
  throw new Error(`Failed to update BDI: ${error.message}`);
342
348
  }
349
+ /**
350
+ * Calcula o BDI total baseado nos itens de composição
351
+ * Fórmula: BDI = ((1 + i_custo) / (1 - i_venda) - 1) * 100
352
+ *
353
+ * Onde:
354
+ * - i_custo = soma dos % que incidem sobre o Custo (ex: Administração, Risco)
355
+ * - i_venda = soma dos % que incidem sobre a Venda (ex: ISS, PIS, COFINS, Lucro)
356
+ */
357
+ export function calculateBdiTotal(items) {
358
+ if (!items || items.length === 0)
359
+ return 0;
360
+ let i_custo = 0;
361
+ let i_venda = 0;
362
+ items.forEach(item => {
363
+ const val = item.percentage / 100;
364
+ if (item.incidence === 'Custo') {
365
+ i_custo += val;
366
+ }
367
+ else {
368
+ // 'Venda' ou qualquer outro valor incide sobre venda
369
+ i_venda += val;
370
+ }
371
+ });
372
+ // Safety check to prevent division by zero or negative results
373
+ if (i_venda >= 1) {
374
+ return 0;
375
+ }
376
+ const bdi = (((1 + i_custo) / (1 - i_venda)) - 1) * 100;
377
+ return bdi;
378
+ }
379
+ /**
380
+ * Prepares adding an item to BDI composition
381
+ */
382
+ export function prepareAddBdiItem(budgetId, bdiType, item) {
383
+ return {
384
+ action: 'add_bdi_item',
385
+ preview: `Adicionar item ao BDI ${bdiType}: "${item.description}" (${item.percentage}%)`,
386
+ data: { budgetId, bdiType, item }
387
+ };
388
+ }
389
+ /**
390
+ * Executes adding item to BDI composition
391
+ * ATUALIZADO: Recalcula automaticamente o BDI total
392
+ */
393
+ export async function executeAddBdiItem(auth, data) {
394
+ const rawData = await getRawBudgetData(data.budgetId);
395
+ if (!rawData)
396
+ throw new Error('Budget not found');
397
+ const bdiField = data.bdiType === 'Principal' ? 'bdiItemsPrincipal' : 'bdiItemsDiferenciado';
398
+ const bdiValueField = data.bdiType === 'Principal' ? 'bdiPrincipal' : 'bdiDiferenciado';
399
+ const currentItems = rawData[bdiField] || [];
400
+ const newItem = {
401
+ id: crypto.randomUUID(),
402
+ description: data.item.description,
403
+ percentage: data.item.percentage,
404
+ incidence: data.item.incidence
405
+ };
406
+ const updatedItems = [...currentItems, newItem];
407
+ const newBdiTotal = calculateBdiTotal(updatedItems);
408
+ const updatedData = {
409
+ ...rawData,
410
+ [bdiField]: updatedItems,
411
+ [bdiValueField]: newBdiTotal
412
+ };
413
+ const { error } = await supabase
414
+ .from('budgets')
415
+ .update({
416
+ data: updatedData,
417
+ last_modified: new Date().toISOString()
418
+ })
419
+ .eq('id', data.budgetId);
420
+ if (error)
421
+ throw new Error(`Failed to add BDI item: ${error.message}`);
422
+ }
423
+ /**
424
+ * Prepares editing an existing BDI item
425
+ */
426
+ export function prepareEditBdiItem(budgetId, bdiType, itemId, updates) {
427
+ const changes = [];
428
+ if (updates.description !== undefined)
429
+ changes.push(`descrição: "${updates.description}"`);
430
+ if (updates.percentage !== undefined)
431
+ changes.push(`percentual: ${updates.percentage}%`);
432
+ if (updates.incidence !== undefined)
433
+ changes.push(`incidência: ${updates.incidence}`);
434
+ return {
435
+ action: 'edit_bdi_item',
436
+ preview: `Editar item do BDI ${bdiType}: ${changes.join(', ')}`,
437
+ data: { budgetId, bdiType, itemId, updates }
438
+ };
439
+ }
440
+ /**
441
+ * Executes editing BDI item
442
+ * ATUALIZADO: Recalcula automaticamente o BDI total
443
+ */
444
+ export async function executeEditBdiItem(auth, data) {
445
+ const rawData = await getRawBudgetData(data.budgetId);
446
+ if (!rawData)
447
+ throw new Error('Budget not found');
448
+ const bdiField = data.bdiType === 'Principal' ? 'bdiItemsPrincipal' : 'bdiItemsDiferenciado';
449
+ const bdiValueField = data.bdiType === 'Principal' ? 'bdiPrincipal' : 'bdiDiferenciado';
450
+ const items = [...(rawData[bdiField] || [])];
451
+ const itemIndex = items.findIndex((item) => item.id === data.itemId);
452
+ if (itemIndex === -1)
453
+ throw new Error('BDI item not found');
454
+ items[itemIndex] = {
455
+ ...items[itemIndex],
456
+ ...data.updates
457
+ };
458
+ const newBdiTotal = calculateBdiTotal(items);
459
+ const updatedData = {
460
+ ...rawData,
461
+ [bdiField]: items,
462
+ [bdiValueField]: newBdiTotal
463
+ };
464
+ const { error } = await supabase
465
+ .from('budgets')
466
+ .update({
467
+ data: updatedData,
468
+ last_modified: new Date().toISOString()
469
+ })
470
+ .eq('id', data.budgetId);
471
+ if (error)
472
+ throw new Error(`Failed to edit BDI item: ${error.message}`);
473
+ }
474
+ /**
475
+ * Prepares removing an item from BDI composition
476
+ */
477
+ export function prepareRemoveBdiItem(budgetId, bdiType, itemId, itemDescription) {
478
+ return {
479
+ action: 'remove_bdi_item',
480
+ preview: `Remover item do BDI ${bdiType}: "${itemDescription}"`,
481
+ data: { budgetId, bdiType, itemId }
482
+ };
483
+ }
484
+ /**
485
+ * Executes removing BDI item
486
+ * ATUALIZADO: Recalcula automaticamente o BDI total
487
+ */
488
+ export async function executeRemoveBdiItem(auth, data) {
489
+ const rawData = await getRawBudgetData(data.budgetId);
490
+ if (!rawData)
491
+ throw new Error('Budget not found');
492
+ const bdiField = data.bdiType === 'Principal' ? 'bdiItemsPrincipal' : 'bdiItemsDiferenciado';
493
+ const bdiValueField = data.bdiType === 'Principal' ? 'bdiPrincipal' : 'bdiDiferenciado';
494
+ const items = [...(rawData[bdiField] || [])];
495
+ const filteredItems = items.filter((item) => item.id !== data.itemId);
496
+ const newBdiTotal = calculateBdiTotal(filteredItems);
497
+ const updatedData = {
498
+ ...rawData,
499
+ [bdiField]: filteredItems,
500
+ [bdiValueField]: newBdiTotal
501
+ };
502
+ const { error } = await supabase
503
+ .from('budgets')
504
+ .update({
505
+ data: updatedData,
506
+ last_modified: new Date().toISOString()
507
+ })
508
+ .eq('id', data.budgetId);
509
+ if (error)
510
+ throw new Error(`Failed to remove BDI item: ${error.message}`);
511
+ }
343
512
  // ================ EDIT ITEM FUNCTIONS ================
344
513
  /**
345
514
  * Prepares editing an existing item
@@ -390,6 +559,8 @@ export async function executeEditItem(auth, data) {
390
559
  item.level = updates.level;
391
560
  if (updates.code !== undefined)
392
561
  item.code = updates.code;
562
+ if (updates.bdiType !== undefined)
563
+ item.bdiType = updates.bdiType;
393
564
  rows[itemIndex] = item;
394
565
  const updatedData = {
395
566
  ...rawData,
@@ -871,3 +1042,245 @@ export async function executeConvertToCost(auth, data) {
871
1042
  if (error)
872
1043
  throw new Error(`Failed to convert to cost: ${error.message}`);
873
1044
  }
1045
+ /**
1046
+ * Lists all tags for a specific budget
1047
+ */
1048
+ export async function getTagsForBudget(budgetId) {
1049
+ const { data, error } = await supabase
1050
+ .from('budget_tags')
1051
+ .select('*')
1052
+ .eq('budget_id', budgetId)
1053
+ .order('created_at', { ascending: true });
1054
+ if (error) {
1055
+ console.error('Error fetching tags:', error);
1056
+ return [];
1057
+ }
1058
+ return data || [];
1059
+ }
1060
+ /**
1061
+ * Prepares adding a tag to a budget
1062
+ */
1063
+ export function prepareAddTag(budgetId, name) {
1064
+ return {
1065
+ action: 'add_tag',
1066
+ preview: `Adicionar rótulo "${name}" ao orçamento`,
1067
+ data: { budgetId, name }
1068
+ };
1069
+ }
1070
+ /**
1071
+ * Executes adding a tag
1072
+ */
1073
+ export async function executeAddTag(auth, data) {
1074
+ const { data: tag, error } = await supabase
1075
+ .from('budget_tags')
1076
+ .insert({ budget_id: data.budgetId, name: data.name })
1077
+ .select()
1078
+ .single();
1079
+ if (error)
1080
+ throw new Error(`Failed to add tag: ${error.message}`);
1081
+ // Update last_modified on budget
1082
+ await supabase
1083
+ .from('budgets')
1084
+ .update({ last_modified: new Date().toISOString() })
1085
+ .eq('id', data.budgetId);
1086
+ return tag;
1087
+ }
1088
+ /**
1089
+ * Prepares editing a tag
1090
+ */
1091
+ export function prepareEditTag(tagId, newName, currentName) {
1092
+ return {
1093
+ action: 'edit_tag',
1094
+ preview: `Renomear rótulo de "${currentName}" para "${newName}"`,
1095
+ data: { tagId, newName }
1096
+ };
1097
+ }
1098
+ /**
1099
+ * Executes editing a tag
1100
+ */
1101
+ export async function executeEditTag(auth, data) {
1102
+ const { error } = await supabase
1103
+ .from('budget_tags')
1104
+ .update({ name: data.newName })
1105
+ .eq('id', data.tagId);
1106
+ if (error)
1107
+ throw new Error(`Failed to edit tag: ${error.message}`);
1108
+ }
1109
+ /**
1110
+ * Prepares removing a tag
1111
+ */
1112
+ export function prepareRemoveTag(tagId, tagName) {
1113
+ return {
1114
+ action: 'remove_tag',
1115
+ preview: `Remover rótulo "${tagName}"`,
1116
+ data: { tagId }
1117
+ };
1118
+ }
1119
+ /**
1120
+ * Executes removing a tag
1121
+ */
1122
+ export async function executeRemoveTag(auth, data) {
1123
+ const { error } = await supabase
1124
+ .from('budget_tags')
1125
+ .delete()
1126
+ .eq('id', data.tagId);
1127
+ if (error)
1128
+ throw new Error(`Failed to remove tag: ${error.message}`);
1129
+ }
1130
+ /**
1131
+ * Lists all projects for the authenticated user's tenant
1132
+ */
1133
+ export async function getProjects(auth) {
1134
+ const { data, error } = await supabase
1135
+ .from('projects')
1136
+ .select('*')
1137
+ .eq('deleted', false)
1138
+ .order('created_at', { ascending: false });
1139
+ if (error) {
1140
+ console.error('Error fetching projects:', error);
1141
+ return [];
1142
+ }
1143
+ return (data || []).map(p => ({
1144
+ id: p.id,
1145
+ code: p.code,
1146
+ name: p.name,
1147
+ description: p.description,
1148
+ created_at: p.created_at,
1149
+ updated_at: p.updated_at
1150
+ }));
1151
+ }
1152
+ /**
1153
+ * Prepares creating a new project
1154
+ */
1155
+ export function prepareCreateProject(name, description, code) {
1156
+ return {
1157
+ action: 'create_project',
1158
+ preview: `Criar projeto "${name}"${code ? ` (${code})` : ''}`,
1159
+ data: { name, description, code }
1160
+ };
1161
+ }
1162
+ /**
1163
+ * Executes creating a project
1164
+ */
1165
+ export async function executeCreateProject(auth, data) {
1166
+ const now = new Date().toISOString();
1167
+ const newProject = {
1168
+ id: crypto.randomUUID(),
1169
+ name: data.name,
1170
+ description: data.description || '',
1171
+ code: data.code || null,
1172
+ user_id: auth.userId,
1173
+ created_at: now,
1174
+ updated_at: now,
1175
+ deleted: false
1176
+ };
1177
+ const { data: project, error } = await supabase
1178
+ .from('projects')
1179
+ .insert(newProject)
1180
+ .select()
1181
+ .single();
1182
+ if (error)
1183
+ throw new Error(`Failed to create project: ${error.message}`);
1184
+ return {
1185
+ id: project.id,
1186
+ code: project.code,
1187
+ name: project.name,
1188
+ description: project.description,
1189
+ created_at: project.created_at,
1190
+ updated_at: project.updated_at
1191
+ };
1192
+ }
1193
+ /**
1194
+ * Prepares editing a project
1195
+ */
1196
+ export function prepareEditProject(projectId, updates, currentName) {
1197
+ const changes = [];
1198
+ if (updates.name)
1199
+ changes.push(`nome: "${updates.name}"`);
1200
+ if (updates.description !== undefined)
1201
+ changes.push(`descrição`);
1202
+ if (updates.code !== undefined)
1203
+ changes.push(`código: "${updates.code}"`);
1204
+ return {
1205
+ action: 'edit_project',
1206
+ preview: `Editar projeto "${currentName}": ${changes.join(', ')}`,
1207
+ data: { projectId, updates }
1208
+ };
1209
+ }
1210
+ /**
1211
+ * Executes editing a project
1212
+ */
1213
+ export async function executeEditProject(auth, data) {
1214
+ const updatePayload = {
1215
+ updated_at: new Date().toISOString()
1216
+ };
1217
+ if (data.updates.name !== undefined)
1218
+ updatePayload.name = data.updates.name;
1219
+ if (data.updates.description !== undefined)
1220
+ updatePayload.description = data.updates.description;
1221
+ if (data.updates.code !== undefined)
1222
+ updatePayload.code = data.updates.code;
1223
+ const { error } = await supabase
1224
+ .from('projects')
1225
+ .update(updatePayload)
1226
+ .eq('id', data.projectId);
1227
+ if (error)
1228
+ throw new Error(`Failed to edit project: ${error.message}`);
1229
+ }
1230
+ /**
1231
+ * Prepares deleting a project (soft delete)
1232
+ */
1233
+ export function prepareDeleteProject(projectId, projectName) {
1234
+ return {
1235
+ action: 'delete_project',
1236
+ preview: `Excluir projeto "${projectName}" (orçamentos serão desvinculados)`,
1237
+ data: { projectId }
1238
+ };
1239
+ }
1240
+ /**
1241
+ * Executes deleting a project (soft delete)
1242
+ */
1243
+ export async function executeDeleteProject(auth, data) {
1244
+ // First, unlink all budgets from this project
1245
+ const { error: unlinkError } = await supabase
1246
+ .from('budgets')
1247
+ .update({ project_id: null })
1248
+ .eq('project_id', data.projectId);
1249
+ if (unlinkError) {
1250
+ console.error('Error unlinking budgets:', unlinkError);
1251
+ }
1252
+ // Soft delete the project
1253
+ const { error } = await supabase
1254
+ .from('projects')
1255
+ .update({ deleted: true })
1256
+ .eq('id', data.projectId);
1257
+ if (error)
1258
+ throw new Error(`Failed to delete project: ${error.message}`);
1259
+ }
1260
+ /**
1261
+ * Prepares linking a budget to a project
1262
+ */
1263
+ export function prepareLinkBudgetToProject(budgetId, projectId, budgetTitle, projectName) {
1264
+ const preview = projectId
1265
+ ? `Vincular orçamento "${budgetTitle}" ao projeto "${projectName}"`
1266
+ : `Desvincular orçamento "${budgetTitle}" de qualquer projeto`;
1267
+ return {
1268
+ action: 'link_budget_to_project',
1269
+ preview,
1270
+ data: { budgetId, projectId }
1271
+ };
1272
+ }
1273
+ /**
1274
+ * Executes linking a budget to a project
1275
+ */
1276
+ export async function executeLinkBudgetToProject(auth, data) {
1277
+ const { error } = await supabase
1278
+ .from('budgets')
1279
+ .update({
1280
+ project_id: data.projectId,
1281
+ last_modified: new Date().toISOString()
1282
+ })
1283
+ .eq('id', data.budgetId);
1284
+ if (error)
1285
+ throw new Error(`Failed to link budget to project: ${error.message}`);
1286
+ }
package/dist/mcp/index.js CHANGED
@@ -246,11 +246,16 @@ O orçamento será criado com BDI zerado (pode ser ajustado depois).`,
246
246
  name: 'quanty_preparar_item',
247
247
  description: `Prepara a adição de um item SIMPLES ao orçamento.
248
248
  Para adicionar COMPOSIÇÕES (serviços com insumos), use quanty_buscar_insumo + quanty_importar_composicao.
249
- Retorna preview e pending_id. Use quanty_executar para confirmar.`,
249
+ Retorna preview e pending_id. Use quanty_executar para confirmar.
250
+
251
+ ⚠️ ATENÇÃO CÓDIGOS: Os códigos são usados para autopreenchimento no sistema.
252
+ Antes de atribuir um código a um item novo, verifique os códigos existentes no orçamento para EVITAR DUPLICAÇÃO.
253
+ Use a aba "Curva ABC" para ver os códigos existentes, ou consulte os itens do orçamento primeiro.`,
250
254
  inputSchema: {
251
255
  type: 'object',
252
256
  properties: {
253
257
  orcamento_id: { type: 'string', description: 'ID do orçamento destino' },
258
+ codigo: { type: 'string', description: 'Código ÚNICO do item. VERIFIQUE se não existe no orçamento antes de usar!' },
254
259
  descricao: { type: 'string', description: 'Descrição do item (ex: "Demolição manual de alvenaria")' },
255
260
  unidade: { type: 'string', description: 'Unidade de medida (m², m³, m, kg, un, h, vb)' },
256
261
  quantidade: { type: 'number', description: 'Quantidade do serviço' },
@@ -267,24 +272,29 @@ Diferente de importar do banco, aqui você define todos os insumos manualmente.
267
272
  O custo unitário da composição é calculado automaticamente pela soma dos custos dos insumos.
268
273
  Retorna preview e pending_id. Use quanty_executar para confirmar.
269
274
 
275
+ ⚠️ ATENÇÃO CÓDIGOS: Os códigos são usados para autopreenchimento no sistema.
276
+ Antes de atribuir códigos, verifique os existentes no orçamento via "Curva ABC" para EVITAR DUPLICAÇÃO.
277
+ Use códigos únicos tanto para a composição quanto para os insumos.
278
+
270
279
  EXEMPLO de uso:
271
280
  {
272
281
  "orcamento_id": "abc123",
282
+ "codigo": "COMP-MeuCodigo",
273
283
  "descricao": "Concretagem de pilar 20x40",
274
284
  "unidade": "m³",
275
285
  "quantidade": 15,
276
286
  "insumos": [
277
- {"descricao": "Concreto fck 30 MPa", "unidade": "m³", "quantidade": 1.05, "custo_unitario": 450.00},
278
- {"descricao": "Forma de madeira", "unidade": "m²", "quantidade": 2.4, "custo_unitario": 85.00},
279
- {"descricao": "Aço CA-50", "unidade": "kg", "quantidade": 120, "custo_unitario": 8.50},
280
- {"descricao": "Pedreiro", "unidade": "h", "quantidade": 4, "custo_unitario": 25.00, "tipo": "MÃO DE OBRA"}
287
+ {"codigo": "INS-001", "descricao": "Concreto fck 30 MPa", "unidade": "m³", "quantidade": 1.05, "custo_unitario": 450.00},
288
+ {"codigo": "INS-002", "descricao": "Forma de madeira", "unidade": "m²", "quantidade": 2.4, "custo_unitario": 85.00},
289
+ {"codigo": "INS-003", "descricao": "Aço CA-50", "unidade": "kg", "quantidade": 120, "custo_unitario": 8.50},
290
+ {"codigo": "MO-001", "descricao": "Pedreiro", "unidade": "h", "quantidade": 4, "custo_unitario": 25.00, "tipo": "MÃO DE OBRA"}
281
291
  ]
282
292
  }`,
283
293
  inputSchema: {
284
294
  type: 'object',
285
295
  properties: {
286
296
  orcamento_id: { type: 'string', description: 'ID do orçamento destino' },
287
- codigo: { type: 'string', description: 'Código opcional da composição (ex: "COMP-001")' },
297
+ codigo: { type: 'string', description: 'Código ÚNICO da composição. VERIFIQUE se não existe no orçamento!' },
288
298
  descricao: { type: 'string', description: 'Descrição da composição (ex: "Concretagem de pilar 20x40")' },
289
299
  unidade: { type: 'string', description: 'Unidade de medida da composição (m², m³, m, un, vb)' },
290
300
  quantidade: { type: 'number', description: 'Quantidade da composição no orçamento' },
@@ -295,7 +305,7 @@ EXEMPLO de uso:
295
305
  items: {
296
306
  type: 'object',
297
307
  properties: {
298
- codigo: { type: 'string', description: 'Código opcional do insumo' },
308
+ codigo: { type: 'string', description: 'Código ÚNICO do insumo. Verifique existentes para evitar duplicação!' },
299
309
  descricao: { type: 'string', description: 'Descrição do insumo' },
300
310
  unidade: { type: 'string', description: 'Unidade do insumo' },
301
311
  quantidade: { type: 'number', description: 'Coeficiente/quantidade do insumo por unidade da composição' },
@@ -380,6 +390,78 @@ Retorna preview e pending_id. Use quanty_executar para confirmar.`,
380
390
  required: ['orcamento_id']
381
391
  }
382
392
  },
393
+ {
394
+ name: 'quanty_adicionar_item_bdi',
395
+ description: `Adiciona um item detalhado à composição do BDI (Principal ou Diferenciado).
396
+ Use esta função para especificar os componentes do BDI, como:
397
+ - Administração Central
398
+ - Lucro
399
+ - Impostos (ISS, PIS, COFINS, etc)
400
+ - Seguros e Garantias
401
+ - Risco
402
+ - Despesas Financeiras
403
+
404
+ O percentual total do BDI será a soma de todos os itens adicionados.`,
405
+ inputSchema: {
406
+ type: 'object',
407
+ properties: {
408
+ orcamento_id: { type: 'string', description: 'ID do orçamento' },
409
+ tipo_bdi: {
410
+ type: 'string',
411
+ enum: ['Principal', 'Diferenciado'],
412
+ description: 'Tipo de BDI: Principal ou Diferenciado'
413
+ },
414
+ descricao: { type: 'string', description: 'Descrição do item (ex: "Administração Central", "Lucro", "ISS")' },
415
+ percentual: { type: 'number', description: 'Percentual do item (ex: 5 para 5%)' },
416
+ incidencia: {
417
+ type: 'string',
418
+ description: 'Sobre o que incide: "Custo Direto", "Preço de Venda", etc',
419
+ default: 'Custo Direto'
420
+ }
421
+ },
422
+ required: ['orcamento_id', 'tipo_bdi', 'descricao', 'percentual']
423
+ }
424
+ },
425
+ {
426
+ name: 'quanty_editar_item_bdi',
427
+ description: `Edita um item existente da composição do BDI.
428
+ Permite alterar descrição, percentual ou incidência de um item específico.`,
429
+ inputSchema: {
430
+ type: 'object',
431
+ properties: {
432
+ orcamento_id: { type: 'string', description: 'ID do orçamento' },
433
+ tipo_bdi: {
434
+ type: 'string',
435
+ enum: ['Principal', 'Diferenciado'],
436
+ description: 'Tipo de BDI'
437
+ },
438
+ item_id: { type: 'string', description: 'ID do item a editar' },
439
+ descricao: { type: 'string', description: 'Nova descrição (opcional)' },
440
+ percentual: { type: 'number', description: 'Novo percentual (opcional)' },
441
+ incidencia: { type: 'string', description: 'Nova incidência (opcional)' }
442
+ },
443
+ required: ['orcamento_id', 'tipo_bdi', 'item_id']
444
+ }
445
+ },
446
+ {
447
+ name: 'quanty_remover_item_bdi',
448
+ description: `Remove um item da composição do BDI.
449
+ Use quanty_abrir_orcamento para obter os IDs dos itens do BDI.`,
450
+ inputSchema: {
451
+ type: 'object',
452
+ properties: {
453
+ orcamento_id: { type: 'string', description: 'ID do orçamento' },
454
+ tipo_bdi: {
455
+ type: 'string',
456
+ enum: ['Principal', 'Diferenciado'],
457
+ description: 'Tipo de BDI'
458
+ },
459
+ item_id: { type: 'string', description: 'ID do item a remover' },
460
+ descricao_item: { type: 'string', description: 'Descrição do item (para confirmação)' }
461
+ },
462
+ required: ['orcamento_id', 'tipo_bdi', 'item_id', 'descricao_item']
463
+ }
464
+ },
383
465
  {
384
466
  name: 'quanty_editar_item',
385
467
  description: `Edita um item EXISTENTE no orçamento.
@@ -534,11 +616,11 @@ Retorna preview e pending_id. Use quanty_executar para confirmar.`,
534
616
  type: 'object',
535
617
  properties: {
536
618
  orcamento_id: { type: 'string', description: 'ID do orçamento' },
537
- item_id: { type: 'string', description: 'ID do item' },
619
+ chave_item: { type: 'string', description: 'CÓDIGO do item da Curva ABC. Se não houver código, usar a DESCRIÇÃO exata.' },
538
620
  classificacao: { type: 'string', enum: ['Custo', 'Material', 'Mão de Obra', 'Equipamento'], description: 'Tipo de classificação ABC' },
539
621
  descricao_item: { type: 'string', description: 'Descrição do item para confirmação' }
540
622
  },
541
- required: ['orcamento_id', 'item_id', 'classificacao']
623
+ required: ['orcamento_id', 'chave_item', 'classificacao']
542
624
  }
543
625
  },
544
626
  // === NEW TOOLS - COMPOSITION EDITING ===
@@ -699,6 +781,107 @@ Retorna preview e pending_id. Use quanty_executar para confirmar.`,
699
781
  },
700
782
  required: ['descricao', 'preco_atual']
701
783
  }
784
+ },
785
+ // === TAGS (RÓTULOS) TOOLS ===
786
+ {
787
+ name: 'quanty_adicionar_tag',
788
+ description: 'Adiciona um rótulo (tag) a um orçamento para organização.',
789
+ inputSchema: {
790
+ type: 'object',
791
+ properties: {
792
+ orcamento_id: { type: 'string', description: 'ID do orçamento' },
793
+ nome_tag: { type: 'string', description: 'Nome do rótulo (ex: "Urgente", "Em análise")' }
794
+ },
795
+ required: ['orcamento_id', 'nome_tag']
796
+ }
797
+ },
798
+ {
799
+ name: 'quanty_editar_tag',
800
+ description: 'Edita o nome de um rótulo existente.',
801
+ inputSchema: {
802
+ type: 'object',
803
+ properties: {
804
+ tag_id: { type: 'string', description: 'ID do rótulo' },
805
+ novo_nome: { type: 'string', description: 'Novo nome do rótulo' },
806
+ nome_atual: { type: 'string', description: 'Nome atual para confirmação' }
807
+ },
808
+ required: ['tag_id', 'novo_nome']
809
+ }
810
+ },
811
+ {
812
+ name: 'quanty_remover_tag',
813
+ description: 'Remove um rótulo de um orçamento.',
814
+ inputSchema: {
815
+ type: 'object',
816
+ properties: {
817
+ tag_id: { type: 'string', description: 'ID do rótulo a remover' },
818
+ nome_tag: { type: 'string', description: 'Nome do rótulo para confirmação' }
819
+ },
820
+ required: ['tag_id']
821
+ }
822
+ },
823
+ // === PROJETOS TOOLS ===
824
+ {
825
+ name: 'quanty_listar_projetos',
826
+ description: 'Lista todos os projetos disponíveis para organizar orçamentos.',
827
+ inputSchema: {
828
+ type: 'object',
829
+ properties: {}
830
+ }
831
+ },
832
+ {
833
+ name: 'quanty_criar_projeto',
834
+ description: 'Cria um novo projeto para organizar orçamentos.',
835
+ inputSchema: {
836
+ type: 'object',
837
+ properties: {
838
+ nome: { type: 'string', description: 'Nome do projeto' },
839
+ descricao: { type: 'string', description: 'Descrição do projeto (opcional)' },
840
+ codigo: { type: 'string', description: 'Código curto do projeto, máx 15 caracteres (opcional)' }
841
+ },
842
+ required: ['nome']
843
+ }
844
+ },
845
+ {
846
+ name: 'quanty_editar_projeto',
847
+ description: 'Edita um projeto existente.',
848
+ inputSchema: {
849
+ type: 'object',
850
+ properties: {
851
+ projeto_id: { type: 'string', description: 'ID do projeto' },
852
+ nome: { type: 'string', description: 'Novo nome (opcional)' },
853
+ descricao: { type: 'string', description: 'Nova descrição (opcional)' },
854
+ codigo: { type: 'string', description: 'Novo código (opcional)' },
855
+ nome_atual: { type: 'string', description: 'Nome atual para confirmação' }
856
+ },
857
+ required: ['projeto_id']
858
+ }
859
+ },
860
+ {
861
+ name: 'quanty_excluir_projeto',
862
+ description: 'Exclui um projeto. Orçamentos vinculados serão desvinculados.',
863
+ inputSchema: {
864
+ type: 'object',
865
+ properties: {
866
+ projeto_id: { type: 'string', description: 'ID do projeto a excluir' },
867
+ nome_projeto: { type: 'string', description: 'Nome do projeto para confirmação' }
868
+ },
869
+ required: ['projeto_id']
870
+ }
871
+ },
872
+ {
873
+ name: 'quanty_vincular_orcamento_projeto',
874
+ description: 'Vincula ou desvincula um orçamento de um projeto.',
875
+ inputSchema: {
876
+ type: 'object',
877
+ properties: {
878
+ orcamento_id: { type: 'string', description: 'ID do orçamento' },
879
+ projeto_id: { type: 'string', description: 'ID do projeto (ou null para desvincular)' },
880
+ titulo_orcamento: { type: 'string', description: 'Título do orçamento para confirmação' },
881
+ nome_projeto: { type: 'string', description: 'Nome do projeto para confirmação' }
882
+ },
883
+ required: ['orcamento_id']
884
+ }
702
885
  }
703
886
  ];
704
887
  async function handleToolCall(auth, name, args) {
@@ -751,8 +934,11 @@ async function handleToolCall(auth, name, args) {
751
934
  return {
752
935
  id: budget.id,
753
936
  titulo: budget.title,
937
+ data_base: budget.baseDate || '',
754
938
  bdi_principal: `${budget.bdiPrincipal}%`,
755
939
  bdi_diferenciado: `${budget.bdiDiferenciado}%`,
940
+ itens_bdi_principal: budget.bdiItemsPrincipal,
941
+ itens_bdi_diferenciado: budget.bdiItemsDiferenciado,
756
942
  valor_total: `R$ ${totalValue.toFixed(2)}`,
757
943
  _info_itens: 'Itens com is_composicao=true são COMPOSIÇÕES que possuem insumos internos',
758
944
  itens: budget.rows.map(r => ({
@@ -958,6 +1144,18 @@ async function handleToolCall(auth, name, args) {
958
1144
  await budgetService.executeUpdateBdi(auth, pending.data);
959
1145
  return { sucesso: true, mensagem: 'BDI atualizado com sucesso!' };
960
1146
  }
1147
+ case 'add_bdi_item': {
1148
+ await budgetService.executeAddBdiItem(auth, pending.data);
1149
+ return { sucesso: true, mensagem: 'Item adicionado à composição do BDI com sucesso!' };
1150
+ }
1151
+ case 'edit_bdi_item': {
1152
+ await budgetService.executeEditBdiItem(auth, pending.data);
1153
+ return { sucesso: true, mensagem: 'Item do BDI editado com sucesso!' };
1154
+ }
1155
+ case 'remove_bdi_item': {
1156
+ await budgetService.executeRemoveBdiItem(auth, pending.data);
1157
+ return { sucesso: true, mensagem: 'Item removido da composição do BDI com sucesso!' };
1158
+ }
961
1159
  case 'edit_item': {
962
1160
  await budgetService.executeEditItem(auth, pending.data);
963
1161
  return { sucesso: true, mensagem: 'Item editado com sucesso!' };
@@ -998,6 +1196,36 @@ async function handleToolCall(auth, name, args) {
998
1196
  await budgetService.executeConvertToCost(auth, pending.data);
999
1197
  return { sucesso: true, mensagem: 'Composição convertida para custo simples com sucesso!' };
1000
1198
  }
1199
+ // === TAGS ===
1200
+ case 'add_tag': {
1201
+ const tag = await budgetService.executeAddTag(auth, pending.data);
1202
+ return { sucesso: true, tag_id: tag.id, mensagem: 'Rótulo adicionado com sucesso!' };
1203
+ }
1204
+ case 'edit_tag': {
1205
+ await budgetService.executeEditTag(auth, pending.data);
1206
+ return { sucesso: true, mensagem: 'Rótulo editado com sucesso!' };
1207
+ }
1208
+ case 'remove_tag': {
1209
+ await budgetService.executeRemoveTag(auth, pending.data);
1210
+ return { sucesso: true, mensagem: 'Rótulo removido com sucesso!' };
1211
+ }
1212
+ // === PROJETOS ===
1213
+ case 'create_project': {
1214
+ const project = await budgetService.executeCreateProject(auth, pending.data);
1215
+ return { sucesso: true, projeto_id: project.id, mensagem: 'Projeto criado com sucesso!' };
1216
+ }
1217
+ case 'edit_project': {
1218
+ await budgetService.executeEditProject(auth, pending.data);
1219
+ return { sucesso: true, mensagem: 'Projeto editado com sucesso!' };
1220
+ }
1221
+ case 'delete_project': {
1222
+ await budgetService.executeDeleteProject(auth, pending.data);
1223
+ return { sucesso: true, mensagem: 'Projeto excluído com sucesso!' };
1224
+ }
1225
+ case 'link_budget_to_project': {
1226
+ await budgetService.executeLinkBudgetToProject(auth, pending.data);
1227
+ return { sucesso: true, mensagem: 'Orçamento vinculado ao projeto com sucesso!' };
1228
+ }
1001
1229
  default:
1002
1230
  return { erro: `Ação desconhecida: ${pending.action}` };
1003
1231
  }
@@ -1063,6 +1291,65 @@ async function handleToolCall(auth, name, args) {
1063
1291
  };
1064
1292
  });
1065
1293
  }
1294
+ case 'quanty_adicionar_item_bdi': {
1295
+ return executeWithLearning(`Adicionar item ao BDI ${args.tipo_bdi}`, async () => {
1296
+ const prepared = budgetService.prepareAddBdiItem(args.orcamento_id, args.tipo_bdi, {
1297
+ description: args.descricao,
1298
+ percentage: args.percentual,
1299
+ incidence: args.incidencia || 'Custo Direto'
1300
+ });
1301
+ const pendingId = generatePendingId();
1302
+ pendingOperations.set(pendingId, {
1303
+ action: prepared.action,
1304
+ data: prepared.data,
1305
+ expiresAt: Date.now() + 5 * 60 * 1000
1306
+ });
1307
+ return {
1308
+ pending_id: pendingId,
1309
+ preview: prepared.preview,
1310
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1311
+ };
1312
+ });
1313
+ }
1314
+ case 'quanty_editar_item_bdi': {
1315
+ return executeWithLearning(`Editar item do BDI ${args.tipo_bdi}`, async () => {
1316
+ const updates = {};
1317
+ if (args.descricao !== undefined)
1318
+ updates.description = args.descricao;
1319
+ if (args.percentual !== undefined)
1320
+ updates.percentage = args.percentual;
1321
+ if (args.incidencia !== undefined)
1322
+ updates.incidence = args.incidencia;
1323
+ const prepared = budgetService.prepareEditBdiItem(args.orcamento_id, args.tipo_bdi, args.item_id, updates);
1324
+ const pendingId = generatePendingId();
1325
+ pendingOperations.set(pendingId, {
1326
+ action: prepared.action,
1327
+ data: prepared.data,
1328
+ expiresAt: Date.now() + 5 * 60 * 1000
1329
+ });
1330
+ return {
1331
+ pending_id: pendingId,
1332
+ preview: prepared.preview,
1333
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1334
+ };
1335
+ });
1336
+ }
1337
+ case 'quanty_remover_item_bdi': {
1338
+ return executeWithLearning(`Remover item do BDI ${args.tipo_bdi}`, async () => {
1339
+ const prepared = budgetService.prepareRemoveBdiItem(args.orcamento_id, args.tipo_bdi, args.item_id, args.descricao_item);
1340
+ const pendingId = generatePendingId();
1341
+ pendingOperations.set(pendingId, {
1342
+ action: prepared.action,
1343
+ data: prepared.data,
1344
+ expiresAt: Date.now() + 5 * 60 * 1000
1345
+ });
1346
+ return {
1347
+ pending_id: pendingId,
1348
+ preview: prepared.preview,
1349
+ mensagem: 'Use quanty_executar com este pending_id para confirmar a remoção.'
1350
+ };
1351
+ });
1352
+ }
1066
1353
  case 'quanty_editar_item': {
1067
1354
  return executeWithLearning(`Editar item`, async () => {
1068
1355
  const updates = {};
@@ -1140,7 +1427,8 @@ async function handleToolCall(auth, name, args) {
1140
1427
  total: `R$ ${item.total.toFixed(2)}`,
1141
1428
  percentual: `${item.percentage}%`,
1142
1429
  acumulado: `${item.accumulated}%`,
1143
- classe: item.class
1430
+ classe: item.class,
1431
+ tipo: item.resourceType
1144
1432
  }))
1145
1433
  };
1146
1434
  });
@@ -1226,7 +1514,9 @@ async function handleToolCall(auth, name, args) {
1226
1514
  }
1227
1515
  case 'quanty_classificar_abc': {
1228
1516
  return executeWithLearning(`Classificar ABC`, async () => {
1229
- const prepared = budgetService.prepareSetAbcClassification(args.orcamento_id, args.item_id, args.classificacao, args.descricao_item || 'Item');
1517
+ const prepared = budgetService.prepareSetAbcClassification(args.orcamento_id, args.chave_item, // Usa código ou descrição como chave
1518
+ args.classificacao, args.chave_item // Usa a própria chave como descrição
1519
+ );
1230
1520
  const pendingId = generatePendingId();
1231
1521
  pendingOperations.set(pendingId, {
1232
1522
  action: prepared.action,
@@ -1451,6 +1741,143 @@ async function handleToolCall(auth, name, args) {
1451
1741
  };
1452
1742
  });
1453
1743
  }
1744
+ // === TAGS (RÓTULOS) HANDLERS ===
1745
+ case 'quanty_adicionar_tag': {
1746
+ return executeWithLearning(`Adicionar tag ao orçamento`, async () => {
1747
+ const prepared = budgetService.prepareAddTag(args.orcamento_id, args.nome_tag);
1748
+ const pendingId = generatePendingId();
1749
+ pendingOperations.set(pendingId, {
1750
+ action: prepared.action,
1751
+ data: prepared.data,
1752
+ expiresAt: Date.now() + 5 * 60 * 1000
1753
+ });
1754
+ return {
1755
+ pending_id: pendingId,
1756
+ preview: prepared.preview,
1757
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1758
+ };
1759
+ });
1760
+ }
1761
+ case 'quanty_editar_tag': {
1762
+ return executeWithLearning(`Editar tag`, async () => {
1763
+ const prepared = budgetService.prepareEditTag(args.tag_id, args.novo_nome, args.nome_atual || 'Tag');
1764
+ const pendingId = generatePendingId();
1765
+ pendingOperations.set(pendingId, {
1766
+ action: prepared.action,
1767
+ data: prepared.data,
1768
+ expiresAt: Date.now() + 5 * 60 * 1000
1769
+ });
1770
+ return {
1771
+ pending_id: pendingId,
1772
+ preview: prepared.preview,
1773
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1774
+ };
1775
+ });
1776
+ }
1777
+ case 'quanty_remover_tag': {
1778
+ return executeWithLearning(`Remover tag`, async () => {
1779
+ const prepared = budgetService.prepareRemoveTag(args.tag_id, args.nome_tag || 'Tag');
1780
+ const pendingId = generatePendingId();
1781
+ pendingOperations.set(pendingId, {
1782
+ action: prepared.action,
1783
+ data: prepared.data,
1784
+ expiresAt: Date.now() + 5 * 60 * 1000
1785
+ });
1786
+ return {
1787
+ pending_id: pendingId,
1788
+ preview: prepared.preview,
1789
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1790
+ };
1791
+ });
1792
+ }
1793
+ // === PROJETOS HANDLERS ===
1794
+ case 'quanty_listar_projetos': {
1795
+ return executeWithLearning(`Listar projetos`, async () => {
1796
+ const projects = await budgetService.getProjects(auth);
1797
+ return {
1798
+ total: projects.length,
1799
+ projetos: projects.map(p => ({
1800
+ id: p.id,
1801
+ codigo: p.code || '',
1802
+ nome: p.name,
1803
+ descricao: p.description || '',
1804
+ criado_em: p.created_at
1805
+ })),
1806
+ _info: 'Use quanty_criar_projeto para criar um novo projeto.'
1807
+ };
1808
+ });
1809
+ }
1810
+ case 'quanty_criar_projeto': {
1811
+ return executeWithLearning(`Criar projeto: ${args.nome}`, async () => {
1812
+ const prepared = budgetService.prepareCreateProject(args.nome, args.descricao, args.codigo);
1813
+ const pendingId = generatePendingId();
1814
+ pendingOperations.set(pendingId, {
1815
+ action: prepared.action,
1816
+ data: prepared.data,
1817
+ expiresAt: Date.now() + 5 * 60 * 1000
1818
+ });
1819
+ return {
1820
+ pending_id: pendingId,
1821
+ preview: prepared.preview,
1822
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1823
+ };
1824
+ });
1825
+ }
1826
+ case 'quanty_editar_projeto': {
1827
+ return executeWithLearning(`Editar projeto`, async () => {
1828
+ const updates = {};
1829
+ if (args.nome !== undefined)
1830
+ updates.name = args.nome;
1831
+ if (args.descricao !== undefined)
1832
+ updates.description = args.descricao;
1833
+ if (args.codigo !== undefined)
1834
+ updates.code = args.codigo;
1835
+ const prepared = budgetService.prepareEditProject(args.projeto_id, updates, args.nome_atual || 'Projeto');
1836
+ const pendingId = generatePendingId();
1837
+ pendingOperations.set(pendingId, {
1838
+ action: prepared.action,
1839
+ data: prepared.data,
1840
+ expiresAt: Date.now() + 5 * 60 * 1000
1841
+ });
1842
+ return {
1843
+ pending_id: pendingId,
1844
+ preview: prepared.preview,
1845
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1846
+ };
1847
+ });
1848
+ }
1849
+ case 'quanty_excluir_projeto': {
1850
+ return executeWithLearning(`Excluir projeto`, async () => {
1851
+ const prepared = budgetService.prepareDeleteProject(args.projeto_id, args.nome_projeto || 'Projeto');
1852
+ const pendingId = generatePendingId();
1853
+ pendingOperations.set(pendingId, {
1854
+ action: prepared.action,
1855
+ data: prepared.data,
1856
+ expiresAt: Date.now() + 5 * 60 * 1000
1857
+ });
1858
+ return {
1859
+ pending_id: pendingId,
1860
+ preview: prepared.preview,
1861
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1862
+ };
1863
+ });
1864
+ }
1865
+ case 'quanty_vincular_orcamento_projeto': {
1866
+ return executeWithLearning(`Vincular orçamento a projeto`, async () => {
1867
+ const prepared = budgetService.prepareLinkBudgetToProject(args.orcamento_id, args.projeto_id || null, args.titulo_orcamento || 'Orçamento', args.nome_projeto || null);
1868
+ const pendingId = generatePendingId();
1869
+ pendingOperations.set(pendingId, {
1870
+ action: prepared.action,
1871
+ data: prepared.data,
1872
+ expiresAt: Date.now() + 5 * 60 * 1000
1873
+ });
1874
+ return {
1875
+ pending_id: pendingId,
1876
+ preview: prepared.preview,
1877
+ mensagem: 'Use quanty_executar com este pending_id para confirmar.'
1878
+ };
1879
+ });
1880
+ }
1454
1881
  default:
1455
1882
  return { erro: `Tool não reconhecida: ${name}` };
1456
1883
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quantyapp/quanty-mcp-server",
3
- "version": "1.2.0",
3
+ "version": "1.2.6",
4
4
  "description": "MCP Server para conectar Claude Desktop ao Quanty - Sistema de Orçamentos de Engenharia",
5
5
  "type": "module",
6
6
  "main": "dist/mcp/index.js",