@run-iq/plugin-fiscal 0.1.0 → 0.2.0

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.
package/dist/index.cjs CHANGED
@@ -40,7 +40,8 @@ __export(index_exports, {
40
40
  ParamsValidator: () => ParamsValidator,
41
41
  ProgressiveBracketModel: () => ProgressiveBracketModel,
42
42
  ScopeResolver: () => ScopeResolver,
43
- ThresholdModel: () => ThresholdModel
43
+ ThresholdModel: () => ThresholdModel,
44
+ fiscalDescriptor: () => fiscalDescriptor
44
45
  });
45
46
  module.exports = __toCommonJS(index_exports);
46
47
 
@@ -290,6 +291,149 @@ var FiscalPlugin = class extends import_plugin_sdk7.BasePlugin {
290
291
  }
291
292
  };
292
293
 
294
+ // src/descriptor.ts
295
+ var fiscalDescriptor = {
296
+ name: "@run-iq/plugin-fiscal",
297
+ version: "0.1.0",
298
+ domainLabel: "fiscal",
299
+ description: "Fiscal domain plugin for tax calculation. Provides 6 universal calculation models applicable to any tax system worldwide: flat rates (VAT/GST/Sales Tax), progressive brackets (income tax), minimum tax floors, threshold-based taxes, fixed levies, and composite multi-step calculations.",
300
+ ruleExtensions: [
301
+ {
302
+ name: "jurisdiction",
303
+ type: "string",
304
+ required: true,
305
+ description: "Tax jurisdiction level. Determines rule priority: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). National laws override regional, which override municipal.",
306
+ enum: ["NATIONAL", "REGIONAL", "MUNICIPAL"]
307
+ },
308
+ {
309
+ name: "scope",
310
+ type: "string",
311
+ required: true,
312
+ description: "Rule application scope. Refines priority within a jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). More specific scope wins over general.",
313
+ enum: ["GLOBAL", "ORGANIZATION", "USER"]
314
+ },
315
+ {
316
+ name: "country",
317
+ type: "string",
318
+ required: true,
319
+ description: 'ISO 3166-1 alpha-2 country code (e.g. "TG" for Togo, "FR" for France, "US" for United States, "IN" for India). Rules are filtered by country at evaluation time via input.meta.context.country.'
320
+ },
321
+ {
322
+ name: "category",
323
+ type: "string",
324
+ required: true,
325
+ description: 'Tax category identifier for grouping in fiscal breakdown. Common values: "TVA" (VAT), "IRPP" (income tax), "IS" (corporate tax), "IMF" (minimum tax), "GST", "SALES_TAX". Free-form string \u2014 use consistent naming per tax system.'
326
+ }
327
+ ],
328
+ inputFields: [
329
+ {
330
+ name: "revenue",
331
+ type: "number",
332
+ description: "Business revenue / turnover (chiffre d'affaires). Used as base for VAT, corporate tax, minimum tax.",
333
+ examples: [1e6, 5e6, 5e7]
334
+ },
335
+ {
336
+ name: "income",
337
+ type: "number",
338
+ description: "Taxable income (revenu imposable). Used as base for progressive income tax brackets.",
339
+ examples: [5e5, 2e6, 1e7]
340
+ },
341
+ {
342
+ name: "expenses",
343
+ type: "number",
344
+ description: "Deductible expenses. Can be used in conditions or composite calculations.",
345
+ examples: [2e5, 1e6]
346
+ },
347
+ {
348
+ name: "netProfit",
349
+ type: "number",
350
+ description: "Net profit (benefice net). Used as base for corporate income tax.",
351
+ examples: [3e5, 5e6]
352
+ }
353
+ ],
354
+ examples: [
355
+ {
356
+ title: "VAT / TVA \u2014 Flat Rate",
357
+ description: "Value-added tax at a flat rate on revenue. Applicable to any country (adjust rate and country code).",
358
+ rule: {
359
+ id: "tg-tva-18",
360
+ model: "FLAT_RATE",
361
+ params: { rate: 0.18, base: "revenue" },
362
+ jurisdiction: "NATIONAL",
363
+ scope: "GLOBAL",
364
+ country: "TG",
365
+ category: "TVA",
366
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
367
+ effectiveUntil: null,
368
+ tags: ["tva", "vat"]
369
+ },
370
+ input: { revenue: 1e6 }
371
+ },
372
+ {
373
+ title: "Income Tax \u2014 Progressive Brackets",
374
+ description: "Progressive income tax with cumulative brackets. Each bracket applies its rate only to the portion of income within its range.",
375
+ rule: {
376
+ id: "tg-irpp-2025",
377
+ model: "PROGRESSIVE_BRACKET",
378
+ params: {
379
+ base: "income",
380
+ brackets: [
381
+ { from: 0, to: 5e5, rate: 0 },
382
+ { from: 5e5, to: 1e6, rate: 0.1 },
383
+ { from: 1e6, to: 3e6, rate: 0.15 },
384
+ { from: 3e6, to: 5e6, rate: 0.25 },
385
+ { from: 5e6, to: null, rate: 0.35 }
386
+ ]
387
+ },
388
+ jurisdiction: "NATIONAL",
389
+ scope: "GLOBAL",
390
+ country: "TG",
391
+ category: "IRPP",
392
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
393
+ effectiveUntil: null,
394
+ tags: ["irpp", "income-tax"]
395
+ },
396
+ input: { income: 2e6 }
397
+ },
398
+ {
399
+ title: "Minimum Tax Floor",
400
+ description: "Minimum tax: MAX(base * rate, fixed minimum). Ensures a minimum tax amount regardless of the proportional calculation.",
401
+ rule: {
402
+ id: "tg-imf-2025",
403
+ model: "MINIMUM_TAX",
404
+ params: { rate: 0.01, base: "revenue", minimum: 5e4 },
405
+ jurisdiction: "NATIONAL",
406
+ scope: "GLOBAL",
407
+ country: "TG",
408
+ category: "IMF",
409
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
410
+ effectiveUntil: null,
411
+ tags: ["imf", "minimum-tax"]
412
+ },
413
+ input: { revenue: 3e6 }
414
+ }
415
+ ],
416
+ promptGuidelines: [
417
+ // Domain universality
418
+ "This plugin provides universal tax calculation models applicable to ANY tax system worldwide \u2014 not limited to any specific country or legal framework.",
419
+ "Always specify the correct ISO 3166-1 alpha-2 country code \u2014 rules are filtered by country at evaluation time.",
420
+ // Model selection
421
+ "Choose the right model for each tax type: FLAT_RATE for proportional taxes (VAT/TVA/GST/Sales Tax), PROGRESSIVE_BRACKET for income tax with cumulative brackets, MINIMUM_TAX for minimum tax floors (MAX of proportional and fixed amount), THRESHOLD for taxes that only apply above a threshold, FIXED_AMOUNT for fixed levies regardless of base, COMPOSITE for multi-step calculations combining sub-models (SUM/MAX/MIN).",
422
+ // Jurisdiction & scope
423
+ "Jurisdiction determines rule priority hierarchy: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). When rules conflict, higher jurisdiction wins.",
424
+ "Scope refines priority within the same jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). A user-specific rule overrides an organization-wide rule at the same jurisdiction level.",
425
+ // Category & breakdown
426
+ 'Use the category field consistently to group related taxes (e.g. "TVA", "IRPP", "IS"). The afterEvaluate hook produces a fiscal breakdown grouped by category \u2014 inconsistent naming breaks grouping.',
427
+ // Analyzing tax legislation
428
+ "When analyzing tax legislation, identify: (1) the tax base \u2014 what amount is being taxed (revenue, income, profit), (2) the rate structure \u2014 flat rate, progressive brackets, minimum floor, (3) any thresholds or exemptions, (4) the jurisdiction level and applicable scope, (5) effective dates and expiry.",
429
+ // Best practices
430
+ 'For progressive bracket taxes, ensure brackets are contiguous (each bracket starts where the previous ends) and the last bracket has "to: null" for uncapped top bracket.',
431
+ 'Use conditions (JSONLogic DSL) to restrict rules to specific taxpayer categories (e.g. revenue >= threshold, business type == "enterprise").',
432
+ "When multiple taxes apply to the same base, create separate rules for each \u2014 the engine evaluates all matching rules and produces a combined breakdown.",
433
+ "Always validate rules after creation to catch missing fields, invalid enums, and checksum mismatches."
434
+ ]
435
+ };
436
+
293
437
  // src/jurisdiction/ScopeResolver.ts
294
438
  var SCOPE_MULTIPLIER2 = {
295
439
  GLOBAL: 1,
@@ -371,6 +515,7 @@ var ParamsValidator = class {
371
515
  ParamsValidator,
372
516
  ProgressiveBracketModel,
373
517
  ScopeResolver,
374
- ThresholdModel
518
+ ThresholdModel,
519
+ fiscalDescriptor
375
520
  });
376
521
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/FiscalPlugin.ts","../src/jurisdiction/JurisdictionResolver.ts","../src/models/FlatRateModel.ts","../src/models/ProgressiveBracketModel.ts","../src/models/MinimumTaxModel.ts","../src/models/ThresholdModel.ts","../src/models/FixedAmountModel.ts","../src/models/CompositeModel.ts","../src/jurisdiction/ScopeResolver.ts","../src/validators/FiscalRuleValidator.ts","../src/validators/ParamsValidator.ts"],"sourcesContent":["export { FiscalPlugin } from './FiscalPlugin.js';\nexport { FlatRateModel } from './models/FlatRateModel.js';\nexport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nexport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nexport { ThresholdModel } from './models/ThresholdModel.js';\nexport { FixedAmountModel } from './models/FixedAmountModel.js';\nexport { CompositeModel } from './models/CompositeModel.js';\nexport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nexport { ScopeResolver } from './jurisdiction/ScopeResolver.js';\nexport { FiscalRuleValidator } from './validators/FiscalRuleValidator.js';\nexport { ParamsValidator } from './validators/ParamsValidator.js';\nexport type { FiscalRule, FiscalScope } from './types/fiscal-rule.js';\nexport type { FiscalJurisdiction } from './types/jurisdiction.js';\nexport type { FiscalCalculationModel } from './types/models.js';\nexport type {\n FlatRateParams,\n BracketParams,\n MinimumTaxParams,\n ThresholdParams,\n FixedAmountParams,\n CompositeParams,\n} from './types/params.js';\n","import { BasePlugin } from '@run-iq/plugin-sdk';\nimport type { EvaluationInput, EvaluationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { FiscalRule } from './types/fiscal-rule.js';\nimport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nimport { FlatRateModel } from './models/FlatRateModel.js';\nimport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nimport { ThresholdModel } from './models/ThresholdModel.js';\nimport { FixedAmountModel } from './models/FixedAmountModel.js';\nimport { CompositeModel } from './models/CompositeModel.js';\n\nexport class FiscalPlugin extends BasePlugin {\n readonly name = '@run-iq/plugin-fiscal' as const;\n readonly version = '0.1.0';\n\n readonly models: CalculationModel[] = [\n new FlatRateModel(),\n new ProgressiveBracketModel(),\n new MinimumTaxModel(),\n new ThresholdModel(),\n new FixedAmountModel(),\n new CompositeModel(),\n ];\n\n override beforeEvaluate(input: EvaluationInput, rules: ReadonlyArray<Rule>): EvaluationInput {\n const fiscalRules = rules as ReadonlyArray<FiscalRule>;\n\n // 1. Resolve priorities from jurisdiction + scope\n const resolvedRules = fiscalRules.map((rule) => ({\n ...rule,\n priority: JurisdictionResolver.resolve(rule.jurisdiction, rule.scope),\n }));\n\n // 2. Filter by country if provided in context\n const country = input.meta.context?.['country'] as string | undefined;\n const filteredRules = country\n ? resolvedRules.filter((r) => r.country === country)\n : resolvedRules;\n\n // IMMUTABLE — return new values\n return {\n ...input,\n data: {\n ...input.data,\n _resolvedRules: filteredRules,\n },\n };\n }\n\n override afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n // Enrich result with fiscal breakdown by category\n const fiscalBreakdown: Record<string, number> = {};\n\n for (const item of result.breakdown) {\n const rule = result.appliedRules.find((r) => r.id === item.ruleId) as FiscalRule | undefined;\n const category = rule?.category ?? 'unknown';\n fiscalBreakdown[category] = (fiscalBreakdown[category] ?? 0) + (item.contribution as number);\n }\n\n return {\n ...result,\n meta: { ...result.meta, fiscalBreakdown },\n };\n }\n}\n","import type { FiscalJurisdiction } from '../types/jurisdiction.js';\nimport type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst JURISDICTION_BASE: Record<FiscalJurisdiction, number> = {\n NATIONAL: 3000,\n REGIONAL: 2000,\n MUNICIPAL: 1000,\n};\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class JurisdictionResolver {\n static resolve(jurisdiction: FiscalJurisdiction, scope: FiscalScope): number {\n const base = JURISDICTION_BASE[jurisdiction];\n const multiplier = SCOPE_MULTIPLIER[scope];\n return Math.round(base * multiplier);\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FlatRateParams } from '../types/params.js';\n\nexport class FlatRateModel extends BaseModel {\n readonly name = 'FLAT_RATE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as FlatRateParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n return baseValue.mul(rate).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { BracketParams } from '../types/params.js';\n\nexport class ProgressiveBracketModel extends BaseModel {\n readonly name = 'PROGRESSIVE_BRACKET' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (typeof p['base'] !== 'string') {\n errors.push('\"base\" must be a string');\n }\n if (!Array.isArray(p['brackets']) || p['brackets'].length === 0) {\n errors.push('\"brackets\" must be a non-empty array');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as BracketParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n let total = new Decimal(0);\n\n for (const bracket of p.brackets) {\n const from = new Decimal(String(bracket.from));\n const to = bracket.to !== null ? new Decimal(String(bracket.to)) : null;\n const rate = new Decimal(String(bracket.rate));\n\n if (baseValue.lte(from)) {\n break;\n }\n\n const taxableInBracket =\n to !== null ? Decimal.min(baseValue, to).minus(from) : baseValue.minus(from);\n\n if (taxableInBracket.gt(0)) {\n total = total.plus(taxableInBracket.mul(rate));\n }\n }\n\n return total.toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { MinimumTaxParams } from '../types/params.js';\n\nexport class MinimumTaxModel extends BaseModel {\n readonly name = 'MINIMUM_TAX' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as MinimumTaxParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n const minimum = new Decimal(String(p.minimum));\n const computed = baseValue.mul(rate);\n return Decimal.max(computed, minimum).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { ThresholdParams } from '../types/params.js';\n\nexport class ThresholdModel extends BaseModel {\n readonly name = 'THRESHOLD_BASED' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as ThresholdParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const threshold = new Decimal(String(p.threshold));\n const rate = new Decimal(String(p.rate));\n\n if (baseValue.lte(threshold)) {\n return 0;\n }\n\n if (p.above_only) {\n return baseValue.minus(threshold).mul(rate).toNumber();\n }\n\n return baseValue.mul(rate).toNumber();\n }\n}\n","import { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FixedAmountParams } from '../types/params.js';\n\nexport class FixedAmountModel extends BaseModel {\n readonly name = 'FIXED_AMOUNT' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n\n calculate(\n _input: Record<string, unknown>,\n _matchedRule: Readonly<Rule>,\n params: unknown,\n ): number {\n const p = params as FixedAmountParams;\n return p.amount;\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { CompositeParams } from '../types/params.js';\nimport { FlatRateModel } from './FlatRateModel.js';\nimport { ProgressiveBracketModel } from './ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './MinimumTaxModel.js';\nimport { ThresholdModel } from './ThresholdModel.js';\nimport { FixedAmountModel } from './FixedAmountModel.js';\n\nconst SUB_MODELS: Record<string, CalculationModel> = {\n FLAT_RATE: new FlatRateModel(),\n PROGRESSIVE_BRACKET: new ProgressiveBracketModel(),\n MINIMUM_TAX: new MinimumTaxModel(),\n THRESHOLD_BASED: new ThresholdModel(),\n FIXED_AMOUNT: new FixedAmountModel(),\n};\n\nexport class CompositeModel extends BaseModel {\n readonly name = 'COMPOSITE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!Array.isArray(p['steps']) || p['steps'].length === 0) {\n errors.push('\"steps\" must be a non-empty array');\n }\n\n const agg = p['aggregation'];\n if (agg !== 'SUM' && agg !== 'MAX' && agg !== 'MIN') {\n errors.push('\"aggregation\" must be SUM, MAX, or MIN');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as CompositeParams;\n const contributions: Decimal[] = [];\n\n for (const step of p.steps) {\n const subModel = SUB_MODELS[step.model];\n if (!subModel) {\n continue;\n }\n const value = subModel.calculate(input, matchedRule, step.params);\n contributions.push(new Decimal(String(value)));\n }\n\n if (contributions.length === 0) {\n return 0;\n }\n\n switch (p.aggregation) {\n case 'SUM':\n return contributions.reduce((acc, v) => acc.plus(v), new Decimal(0)).toNumber();\n case 'MAX':\n return Decimal.max(...contributions).toNumber();\n case 'MIN':\n return Decimal.min(...contributions).toNumber();\n }\n }\n}\n","import type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class ScopeResolver {\n static getMultiplier(scope: FiscalScope): number {\n return SCOPE_MULTIPLIER[scope];\n }\n}\n","import type { FiscalRule } from '../types/fiscal-rule.js';\n\nconst VALID_JURISDICTIONS = ['NATIONAL', 'REGIONAL', 'MUNICIPAL'];\nconst VALID_SCOPES = ['GLOBAL', 'ORGANIZATION', 'USER'];\n\nexport class FiscalRuleValidator {\n static validate(rule: unknown): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n if (rule === null || typeof rule !== 'object') {\n return { valid: false, errors: ['rule must be an object'] };\n }\n\n const r = rule as Partial<FiscalRule>;\n\n if (!r.jurisdiction || !VALID_JURISDICTIONS.includes(r.jurisdiction)) {\n errors.push(`jurisdiction must be one of: ${VALID_JURISDICTIONS.join(', ')}`);\n }\n if (!r.scope || !VALID_SCOPES.includes(r.scope)) {\n errors.push(`scope must be one of: ${VALID_SCOPES.join(', ')}`);\n }\n if (typeof r.country !== 'string' || r.country.length === 0) {\n errors.push('country must be a non-empty string');\n }\n if (typeof r.category !== 'string' || r.category.length === 0) {\n errors.push('category must be a non-empty string');\n }\n\n return { valid: errors.length === 0, errors };\n }\n}\n","import { SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult } from '@run-iq/core';\n\nexport class ParamsValidator {\n static validateFlatRate(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n static validateMinimumTax(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n static validateThreshold(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n static validateFixedAmount(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n}\n"],"mappings":"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","names":["import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_plugin_sdk","import_decimal","import_plugin_sdk","Decimal","SCOPE_MULTIPLIER","import_plugin_sdk"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/FiscalPlugin.ts","../src/jurisdiction/JurisdictionResolver.ts","../src/models/FlatRateModel.ts","../src/models/ProgressiveBracketModel.ts","../src/models/MinimumTaxModel.ts","../src/models/ThresholdModel.ts","../src/models/FixedAmountModel.ts","../src/models/CompositeModel.ts","../src/descriptor.ts","../src/jurisdiction/ScopeResolver.ts","../src/validators/FiscalRuleValidator.ts","../src/validators/ParamsValidator.ts"],"sourcesContent":["export { FiscalPlugin } from './FiscalPlugin.js';\nexport { fiscalDescriptor } from './descriptor.js';\nexport { FlatRateModel } from './models/FlatRateModel.js';\nexport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nexport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nexport { ThresholdModel } from './models/ThresholdModel.js';\nexport { FixedAmountModel } from './models/FixedAmountModel.js';\nexport { CompositeModel } from './models/CompositeModel.js';\nexport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nexport { ScopeResolver } from './jurisdiction/ScopeResolver.js';\nexport { FiscalRuleValidator } from './validators/FiscalRuleValidator.js';\nexport { ParamsValidator } from './validators/ParamsValidator.js';\nexport type { FiscalRule, FiscalScope } from './types/fiscal-rule.js';\nexport type { FiscalJurisdiction } from './types/jurisdiction.js';\nexport type { FiscalCalculationModel } from './types/models.js';\nexport type {\n FlatRateParams,\n BracketParams,\n MinimumTaxParams,\n ThresholdParams,\n FixedAmountParams,\n CompositeParams,\n} from './types/params.js';\n","import { BasePlugin } from '@run-iq/plugin-sdk';\nimport type { EvaluationInput, EvaluationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { FiscalRule } from './types/fiscal-rule.js';\nimport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nimport { FlatRateModel } from './models/FlatRateModel.js';\nimport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nimport { ThresholdModel } from './models/ThresholdModel.js';\nimport { FixedAmountModel } from './models/FixedAmountModel.js';\nimport { CompositeModel } from './models/CompositeModel.js';\n\nexport class FiscalPlugin extends BasePlugin {\n readonly name = '@run-iq/plugin-fiscal' as const;\n readonly version = '0.1.0';\n\n readonly models: CalculationModel[] = [\n new FlatRateModel(),\n new ProgressiveBracketModel(),\n new MinimumTaxModel(),\n new ThresholdModel(),\n new FixedAmountModel(),\n new CompositeModel(),\n ];\n\n override beforeEvaluate(input: EvaluationInput, rules: ReadonlyArray<Rule>): EvaluationInput {\n const fiscalRules = rules as ReadonlyArray<FiscalRule>;\n\n // 1. Resolve priorities from jurisdiction + scope\n const resolvedRules = fiscalRules.map((rule) => ({\n ...rule,\n priority: JurisdictionResolver.resolve(rule.jurisdiction, rule.scope),\n }));\n\n // 2. Filter by country if provided in context\n const country = input.meta.context?.['country'] as string | undefined;\n const filteredRules = country\n ? resolvedRules.filter((r) => r.country === country)\n : resolvedRules;\n\n // IMMUTABLE — return new values\n return {\n ...input,\n data: {\n ...input.data,\n _resolvedRules: filteredRules,\n },\n };\n }\n\n override afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n // Enrich result with fiscal breakdown by category\n const fiscalBreakdown: Record<string, number> = {};\n\n for (const item of result.breakdown) {\n const rule = result.appliedRules.find((r) => r.id === item.ruleId) as FiscalRule | undefined;\n const category = rule?.category ?? 'unknown';\n fiscalBreakdown[category] = (fiscalBreakdown[category] ?? 0) + (item.contribution as number);\n }\n\n return {\n ...result,\n meta: { ...result.meta, fiscalBreakdown },\n };\n }\n}\n","import type { FiscalJurisdiction } from '../types/jurisdiction.js';\nimport type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst JURISDICTION_BASE: Record<FiscalJurisdiction, number> = {\n NATIONAL: 3000,\n REGIONAL: 2000,\n MUNICIPAL: 1000,\n};\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class JurisdictionResolver {\n static resolve(jurisdiction: FiscalJurisdiction, scope: FiscalScope): number {\n const base = JURISDICTION_BASE[jurisdiction];\n const multiplier = SCOPE_MULTIPLIER[scope];\n return Math.round(base * multiplier);\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FlatRateParams } from '../types/params.js';\n\nexport class FlatRateModel extends BaseModel {\n readonly name = 'FLAT_RATE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as FlatRateParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n return baseValue.mul(rate).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { BracketParams } from '../types/params.js';\n\nexport class ProgressiveBracketModel extends BaseModel {\n readonly name = 'PROGRESSIVE_BRACKET' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (typeof p['base'] !== 'string') {\n errors.push('\"base\" must be a string');\n }\n if (!Array.isArray(p['brackets']) || p['brackets'].length === 0) {\n errors.push('\"brackets\" must be a non-empty array');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as BracketParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n let total = new Decimal(0);\n\n for (const bracket of p.brackets) {\n const from = new Decimal(String(bracket.from));\n const to = bracket.to !== null ? new Decimal(String(bracket.to)) : null;\n const rate = new Decimal(String(bracket.rate));\n\n if (baseValue.lte(from)) {\n break;\n }\n\n const taxableInBracket =\n to !== null ? Decimal.min(baseValue, to).minus(from) : baseValue.minus(from);\n\n if (taxableInBracket.gt(0)) {\n total = total.plus(taxableInBracket.mul(rate));\n }\n }\n\n return total.toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { MinimumTaxParams } from '../types/params.js';\n\nexport class MinimumTaxModel extends BaseModel {\n readonly name = 'MINIMUM_TAX' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as MinimumTaxParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n const minimum = new Decimal(String(p.minimum));\n const computed = baseValue.mul(rate);\n return Decimal.max(computed, minimum).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { ThresholdParams } from '../types/params.js';\n\nexport class ThresholdModel extends BaseModel {\n readonly name = 'THRESHOLD_BASED' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as ThresholdParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const threshold = new Decimal(String(p.threshold));\n const rate = new Decimal(String(p.rate));\n\n if (baseValue.lte(threshold)) {\n return 0;\n }\n\n if (p.above_only) {\n return baseValue.minus(threshold).mul(rate).toNumber();\n }\n\n return baseValue.mul(rate).toNumber();\n }\n}\n","import { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FixedAmountParams } from '../types/params.js';\n\nexport class FixedAmountModel extends BaseModel {\n readonly name = 'FIXED_AMOUNT' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n\n calculate(\n _input: Record<string, unknown>,\n _matchedRule: Readonly<Rule>,\n params: unknown,\n ): number {\n const p = params as FixedAmountParams;\n return p.amount;\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { CompositeParams } from '../types/params.js';\nimport { FlatRateModel } from './FlatRateModel.js';\nimport { ProgressiveBracketModel } from './ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './MinimumTaxModel.js';\nimport { ThresholdModel } from './ThresholdModel.js';\nimport { FixedAmountModel } from './FixedAmountModel.js';\n\nconst SUB_MODELS: Record<string, CalculationModel> = {\n FLAT_RATE: new FlatRateModel(),\n PROGRESSIVE_BRACKET: new ProgressiveBracketModel(),\n MINIMUM_TAX: new MinimumTaxModel(),\n THRESHOLD_BASED: new ThresholdModel(),\n FIXED_AMOUNT: new FixedAmountModel(),\n};\n\nexport class CompositeModel extends BaseModel {\n readonly name = 'COMPOSITE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!Array.isArray(p['steps']) || p['steps'].length === 0) {\n errors.push('\"steps\" must be a non-empty array');\n }\n\n const agg = p['aggregation'];\n if (agg !== 'SUM' && agg !== 'MAX' && agg !== 'MIN') {\n errors.push('\"aggregation\" must be SUM, MAX, or MIN');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as CompositeParams;\n const contributions: Decimal[] = [];\n\n for (const step of p.steps) {\n const subModel = SUB_MODELS[step.model];\n if (!subModel) {\n continue;\n }\n const value = subModel.calculate(input, matchedRule, step.params);\n contributions.push(new Decimal(String(value)));\n }\n\n if (contributions.length === 0) {\n return 0;\n }\n\n switch (p.aggregation) {\n case 'SUM':\n return contributions.reduce((acc, v) => acc.plus(v), new Decimal(0)).toNumber();\n case 'MAX':\n return Decimal.max(...contributions).toNumber();\n case 'MIN':\n return Decimal.min(...contributions).toNumber();\n }\n }\n}\n","import type { PluginDescriptor } from '@run-iq/plugin-sdk';\n\nexport const fiscalDescriptor: PluginDescriptor = {\n name: '@run-iq/plugin-fiscal',\n version: '0.1.0',\n domainLabel: 'fiscal',\n description:\n 'Fiscal domain plugin for tax calculation. Provides 6 universal calculation models applicable to any tax system worldwide: flat rates (VAT/GST/Sales Tax), progressive brackets (income tax), minimum tax floors, threshold-based taxes, fixed levies, and composite multi-step calculations.',\n\n ruleExtensions: [\n {\n name: 'jurisdiction',\n type: 'string',\n required: true,\n description:\n 'Tax jurisdiction level. Determines rule priority: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). National laws override regional, which override municipal.',\n enum: ['NATIONAL', 'REGIONAL', 'MUNICIPAL'],\n },\n {\n name: 'scope',\n type: 'string',\n required: true,\n description:\n 'Rule application scope. Refines priority within a jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). More specific scope wins over general.',\n enum: ['GLOBAL', 'ORGANIZATION', 'USER'],\n },\n {\n name: 'country',\n type: 'string',\n required: true,\n description:\n 'ISO 3166-1 alpha-2 country code (e.g. \"TG\" for Togo, \"FR\" for France, \"US\" for United States, \"IN\" for India). Rules are filtered by country at evaluation time via input.meta.context.country.',\n },\n {\n name: 'category',\n type: 'string',\n required: true,\n description:\n 'Tax category identifier for grouping in fiscal breakdown. Common values: \"TVA\" (VAT), \"IRPP\" (income tax), \"IS\" (corporate tax), \"IMF\" (minimum tax), \"GST\", \"SALES_TAX\". Free-form string — use consistent naming per tax system.',\n },\n ],\n\n inputFields: [\n {\n name: 'revenue',\n type: 'number',\n description:\n \"Business revenue / turnover (chiffre d'affaires). Used as base for VAT, corporate tax, minimum tax.\",\n examples: [1_000_000, 5_000_000, 50_000_000],\n },\n {\n name: 'income',\n type: 'number',\n description:\n 'Taxable income (revenu imposable). Used as base for progressive income tax brackets.',\n examples: [500_000, 2_000_000, 10_000_000],\n },\n {\n name: 'expenses',\n type: 'number',\n description: 'Deductible expenses. Can be used in conditions or composite calculations.',\n examples: [200_000, 1_000_000],\n },\n {\n name: 'netProfit',\n type: 'number',\n description: 'Net profit (benefice net). Used as base for corporate income tax.',\n examples: [300_000, 5_000_000],\n },\n ],\n\n examples: [\n {\n title: 'VAT / TVA — Flat Rate',\n description:\n 'Value-added tax at a flat rate on revenue. Applicable to any country (adjust rate and country code).',\n rule: {\n id: 'tg-tva-18',\n model: 'FLAT_RATE',\n params: { rate: 0.18, base: 'revenue' },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'TVA',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['tva', 'vat'],\n },\n input: { revenue: 1_000_000 },\n },\n {\n title: 'Income Tax — Progressive Brackets',\n description:\n 'Progressive income tax with cumulative brackets. Each bracket applies its rate only to the portion of income within its range.',\n rule: {\n id: 'tg-irpp-2025',\n model: 'PROGRESSIVE_BRACKET',\n params: {\n base: 'income',\n brackets: [\n { from: 0, to: 500_000, rate: 0 },\n { from: 500_000, to: 1_000_000, rate: 0.1 },\n { from: 1_000_000, to: 3_000_000, rate: 0.15 },\n { from: 3_000_000, to: 5_000_000, rate: 0.25 },\n { from: 5_000_000, to: null, rate: 0.35 },\n ],\n },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'IRPP',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['irpp', 'income-tax'],\n },\n input: { income: 2_000_000 },\n },\n {\n title: 'Minimum Tax Floor',\n description:\n 'Minimum tax: MAX(base * rate, fixed minimum). Ensures a minimum tax amount regardless of the proportional calculation.',\n rule: {\n id: 'tg-imf-2025',\n model: 'MINIMUM_TAX',\n params: { rate: 0.01, base: 'revenue', minimum: 50_000 },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'IMF',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['imf', 'minimum-tax'],\n },\n input: { revenue: 3_000_000 },\n },\n ],\n\n promptGuidelines: [\n // Domain universality\n 'This plugin provides universal tax calculation models applicable to ANY tax system worldwide — not limited to any specific country or legal framework.',\n 'Always specify the correct ISO 3166-1 alpha-2 country code — rules are filtered by country at evaluation time.',\n\n // Model selection\n 'Choose the right model for each tax type: FLAT_RATE for proportional taxes (VAT/TVA/GST/Sales Tax), PROGRESSIVE_BRACKET for income tax with cumulative brackets, MINIMUM_TAX for minimum tax floors (MAX of proportional and fixed amount), THRESHOLD for taxes that only apply above a threshold, FIXED_AMOUNT for fixed levies regardless of base, COMPOSITE for multi-step calculations combining sub-models (SUM/MAX/MIN).',\n\n // Jurisdiction & scope\n 'Jurisdiction determines rule priority hierarchy: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). When rules conflict, higher jurisdiction wins.',\n 'Scope refines priority within the same jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). A user-specific rule overrides an organization-wide rule at the same jurisdiction level.',\n\n // Category & breakdown\n 'Use the category field consistently to group related taxes (e.g. \"TVA\", \"IRPP\", \"IS\"). The afterEvaluate hook produces a fiscal breakdown grouped by category — inconsistent naming breaks grouping.',\n\n // Analyzing tax legislation\n 'When analyzing tax legislation, identify: (1) the tax base — what amount is being taxed (revenue, income, profit), (2) the rate structure — flat rate, progressive brackets, minimum floor, (3) any thresholds or exemptions, (4) the jurisdiction level and applicable scope, (5) effective dates and expiry.',\n\n // Best practices\n 'For progressive bracket taxes, ensure brackets are contiguous (each bracket starts where the previous ends) and the last bracket has \"to: null\" for uncapped top bracket.',\n 'Use conditions (JSONLogic DSL) to restrict rules to specific taxpayer categories (e.g. revenue >= threshold, business type == \"enterprise\").',\n 'When multiple taxes apply to the same base, create separate rules for each — the engine evaluates all matching rules and produces a combined breakdown.',\n 'Always validate rules after creation to catch missing fields, invalid enums, and checksum mismatches.',\n ],\n};\n","import type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class ScopeResolver {\n static getMultiplier(scope: FiscalScope): number {\n return SCOPE_MULTIPLIER[scope];\n }\n}\n","import type { FiscalRule } from '../types/fiscal-rule.js';\n\nconst VALID_JURISDICTIONS = ['NATIONAL', 'REGIONAL', 'MUNICIPAL'];\nconst VALID_SCOPES = ['GLOBAL', 'ORGANIZATION', 'USER'];\n\nexport class FiscalRuleValidator {\n static validate(rule: unknown): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n if (rule === null || typeof rule !== 'object') {\n return { valid: false, errors: ['rule must be an object'] };\n }\n\n const r = rule as Partial<FiscalRule>;\n\n if (!r.jurisdiction || !VALID_JURISDICTIONS.includes(r.jurisdiction)) {\n errors.push(`jurisdiction must be one of: ${VALID_JURISDICTIONS.join(', ')}`);\n }\n if (!r.scope || !VALID_SCOPES.includes(r.scope)) {\n errors.push(`scope must be one of: ${VALID_SCOPES.join(', ')}`);\n }\n if (typeof r.country !== 'string' || r.country.length === 0) {\n errors.push('country must be a non-empty string');\n }\n if (typeof r.category !== 'string' || r.category.length === 0) {\n errors.push('category must be a non-empty string');\n }\n\n return { valid: errors.length === 0, errors };\n }\n}\n","import { SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult } from '@run-iq/core';\n\nexport class ParamsValidator {\n static validateFlatRate(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n static validateMinimumTax(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n static validateThreshold(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n static validateFixedAmount(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n}\n"],"mappings":"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","names":["import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_decimal","import_plugin_sdk","Decimal","import_plugin_sdk","import_decimal","import_plugin_sdk","Decimal","SCOPE_MULTIPLIER","import_plugin_sdk"]}
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { BasePlugin, BaseModel } from '@run-iq/plugin-sdk';
1
+ import { BasePlugin, PluginDescriptor, BaseModel } from '@run-iq/plugin-sdk';
2
2
  import { CalculationModel, EvaluationInput, Rule, EvaluationResult, ValidationResult } from '@run-iq/core';
3
3
 
4
4
  declare class FiscalPlugin extends BasePlugin {
@@ -9,6 +9,8 @@ declare class FiscalPlugin extends BasePlugin {
9
9
  afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult;
10
10
  }
11
11
 
12
+ declare const fiscalDescriptor: PluginDescriptor;
13
+
12
14
  declare class FlatRateModel extends BaseModel {
13
15
  readonly name: "FLAT_RATE";
14
16
  readonly version = "1.0.0";
@@ -123,4 +125,4 @@ declare class ParamsValidator {
123
125
  static validateFixedAmount(params: unknown): ValidationResult;
124
126
  }
125
127
 
126
- export { type BracketParams, CompositeModel, type CompositeParams, type FiscalCalculationModel, type FiscalJurisdiction, FiscalPlugin, type FiscalRule, FiscalRuleValidator, type FiscalScope, FixedAmountModel, type FixedAmountParams, FlatRateModel, type FlatRateParams, JurisdictionResolver, MinimumTaxModel, type MinimumTaxParams, ParamsValidator, ProgressiveBracketModel, ScopeResolver, ThresholdModel, type ThresholdParams };
128
+ export { type BracketParams, CompositeModel, type CompositeParams, type FiscalCalculationModel, type FiscalJurisdiction, FiscalPlugin, type FiscalRule, FiscalRuleValidator, type FiscalScope, FixedAmountModel, type FixedAmountParams, FlatRateModel, type FlatRateParams, JurisdictionResolver, MinimumTaxModel, type MinimumTaxParams, ParamsValidator, ProgressiveBracketModel, ScopeResolver, ThresholdModel, type ThresholdParams, fiscalDescriptor };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BasePlugin, BaseModel } from '@run-iq/plugin-sdk';
1
+ import { BasePlugin, PluginDescriptor, BaseModel } from '@run-iq/plugin-sdk';
2
2
  import { CalculationModel, EvaluationInput, Rule, EvaluationResult, ValidationResult } from '@run-iq/core';
3
3
 
4
4
  declare class FiscalPlugin extends BasePlugin {
@@ -9,6 +9,8 @@ declare class FiscalPlugin extends BasePlugin {
9
9
  afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult;
10
10
  }
11
11
 
12
+ declare const fiscalDescriptor: PluginDescriptor;
13
+
12
14
  declare class FlatRateModel extends BaseModel {
13
15
  readonly name: "FLAT_RATE";
14
16
  readonly version = "1.0.0";
@@ -123,4 +125,4 @@ declare class ParamsValidator {
123
125
  static validateFixedAmount(params: unknown): ValidationResult;
124
126
  }
125
127
 
126
- export { type BracketParams, CompositeModel, type CompositeParams, type FiscalCalculationModel, type FiscalJurisdiction, FiscalPlugin, type FiscalRule, FiscalRuleValidator, type FiscalScope, FixedAmountModel, type FixedAmountParams, FlatRateModel, type FlatRateParams, JurisdictionResolver, MinimumTaxModel, type MinimumTaxParams, ParamsValidator, ProgressiveBracketModel, ScopeResolver, ThresholdModel, type ThresholdParams };
128
+ export { type BracketParams, CompositeModel, type CompositeParams, type FiscalCalculationModel, type FiscalJurisdiction, FiscalPlugin, type FiscalRule, FiscalRuleValidator, type FiscalScope, FixedAmountModel, type FixedAmountParams, FlatRateModel, type FlatRateParams, JurisdictionResolver, MinimumTaxModel, type MinimumTaxParams, ParamsValidator, ProgressiveBracketModel, ScopeResolver, ThresholdModel, type ThresholdParams, fiscalDescriptor };
package/dist/index.js CHANGED
@@ -244,6 +244,149 @@ var FiscalPlugin = class extends BasePlugin {
244
244
  }
245
245
  };
246
246
 
247
+ // src/descriptor.ts
248
+ var fiscalDescriptor = {
249
+ name: "@run-iq/plugin-fiscal",
250
+ version: "0.1.0",
251
+ domainLabel: "fiscal",
252
+ description: "Fiscal domain plugin for tax calculation. Provides 6 universal calculation models applicable to any tax system worldwide: flat rates (VAT/GST/Sales Tax), progressive brackets (income tax), minimum tax floors, threshold-based taxes, fixed levies, and composite multi-step calculations.",
253
+ ruleExtensions: [
254
+ {
255
+ name: "jurisdiction",
256
+ type: "string",
257
+ required: true,
258
+ description: "Tax jurisdiction level. Determines rule priority: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). National laws override regional, which override municipal.",
259
+ enum: ["NATIONAL", "REGIONAL", "MUNICIPAL"]
260
+ },
261
+ {
262
+ name: "scope",
263
+ type: "string",
264
+ required: true,
265
+ description: "Rule application scope. Refines priority within a jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). More specific scope wins over general.",
266
+ enum: ["GLOBAL", "ORGANIZATION", "USER"]
267
+ },
268
+ {
269
+ name: "country",
270
+ type: "string",
271
+ required: true,
272
+ description: 'ISO 3166-1 alpha-2 country code (e.g. "TG" for Togo, "FR" for France, "US" for United States, "IN" for India). Rules are filtered by country at evaluation time via input.meta.context.country.'
273
+ },
274
+ {
275
+ name: "category",
276
+ type: "string",
277
+ required: true,
278
+ description: 'Tax category identifier for grouping in fiscal breakdown. Common values: "TVA" (VAT), "IRPP" (income tax), "IS" (corporate tax), "IMF" (minimum tax), "GST", "SALES_TAX". Free-form string \u2014 use consistent naming per tax system.'
279
+ }
280
+ ],
281
+ inputFields: [
282
+ {
283
+ name: "revenue",
284
+ type: "number",
285
+ description: "Business revenue / turnover (chiffre d'affaires). Used as base for VAT, corporate tax, minimum tax.",
286
+ examples: [1e6, 5e6, 5e7]
287
+ },
288
+ {
289
+ name: "income",
290
+ type: "number",
291
+ description: "Taxable income (revenu imposable). Used as base for progressive income tax brackets.",
292
+ examples: [5e5, 2e6, 1e7]
293
+ },
294
+ {
295
+ name: "expenses",
296
+ type: "number",
297
+ description: "Deductible expenses. Can be used in conditions or composite calculations.",
298
+ examples: [2e5, 1e6]
299
+ },
300
+ {
301
+ name: "netProfit",
302
+ type: "number",
303
+ description: "Net profit (benefice net). Used as base for corporate income tax.",
304
+ examples: [3e5, 5e6]
305
+ }
306
+ ],
307
+ examples: [
308
+ {
309
+ title: "VAT / TVA \u2014 Flat Rate",
310
+ description: "Value-added tax at a flat rate on revenue. Applicable to any country (adjust rate and country code).",
311
+ rule: {
312
+ id: "tg-tva-18",
313
+ model: "FLAT_RATE",
314
+ params: { rate: 0.18, base: "revenue" },
315
+ jurisdiction: "NATIONAL",
316
+ scope: "GLOBAL",
317
+ country: "TG",
318
+ category: "TVA",
319
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
320
+ effectiveUntil: null,
321
+ tags: ["tva", "vat"]
322
+ },
323
+ input: { revenue: 1e6 }
324
+ },
325
+ {
326
+ title: "Income Tax \u2014 Progressive Brackets",
327
+ description: "Progressive income tax with cumulative brackets. Each bracket applies its rate only to the portion of income within its range.",
328
+ rule: {
329
+ id: "tg-irpp-2025",
330
+ model: "PROGRESSIVE_BRACKET",
331
+ params: {
332
+ base: "income",
333
+ brackets: [
334
+ { from: 0, to: 5e5, rate: 0 },
335
+ { from: 5e5, to: 1e6, rate: 0.1 },
336
+ { from: 1e6, to: 3e6, rate: 0.15 },
337
+ { from: 3e6, to: 5e6, rate: 0.25 },
338
+ { from: 5e6, to: null, rate: 0.35 }
339
+ ]
340
+ },
341
+ jurisdiction: "NATIONAL",
342
+ scope: "GLOBAL",
343
+ country: "TG",
344
+ category: "IRPP",
345
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
346
+ effectiveUntil: null,
347
+ tags: ["irpp", "income-tax"]
348
+ },
349
+ input: { income: 2e6 }
350
+ },
351
+ {
352
+ title: "Minimum Tax Floor",
353
+ description: "Minimum tax: MAX(base * rate, fixed minimum). Ensures a minimum tax amount regardless of the proportional calculation.",
354
+ rule: {
355
+ id: "tg-imf-2025",
356
+ model: "MINIMUM_TAX",
357
+ params: { rate: 0.01, base: "revenue", minimum: 5e4 },
358
+ jurisdiction: "NATIONAL",
359
+ scope: "GLOBAL",
360
+ country: "TG",
361
+ category: "IMF",
362
+ effectiveFrom: "2025-01-01T00:00:00.000Z",
363
+ effectiveUntil: null,
364
+ tags: ["imf", "minimum-tax"]
365
+ },
366
+ input: { revenue: 3e6 }
367
+ }
368
+ ],
369
+ promptGuidelines: [
370
+ // Domain universality
371
+ "This plugin provides universal tax calculation models applicable to ANY tax system worldwide \u2014 not limited to any specific country or legal framework.",
372
+ "Always specify the correct ISO 3166-1 alpha-2 country code \u2014 rules are filtered by country at evaluation time.",
373
+ // Model selection
374
+ "Choose the right model for each tax type: FLAT_RATE for proportional taxes (VAT/TVA/GST/Sales Tax), PROGRESSIVE_BRACKET for income tax with cumulative brackets, MINIMUM_TAX for minimum tax floors (MAX of proportional and fixed amount), THRESHOLD for taxes that only apply above a threshold, FIXED_AMOUNT for fixed levies regardless of base, COMPOSITE for multi-step calculations combining sub-models (SUM/MAX/MIN).",
375
+ // Jurisdiction & scope
376
+ "Jurisdiction determines rule priority hierarchy: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). When rules conflict, higher jurisdiction wins.",
377
+ "Scope refines priority within the same jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). A user-specific rule overrides an organization-wide rule at the same jurisdiction level.",
378
+ // Category & breakdown
379
+ 'Use the category field consistently to group related taxes (e.g. "TVA", "IRPP", "IS"). The afterEvaluate hook produces a fiscal breakdown grouped by category \u2014 inconsistent naming breaks grouping.',
380
+ // Analyzing tax legislation
381
+ "When analyzing tax legislation, identify: (1) the tax base \u2014 what amount is being taxed (revenue, income, profit), (2) the rate structure \u2014 flat rate, progressive brackets, minimum floor, (3) any thresholds or exemptions, (4) the jurisdiction level and applicable scope, (5) effective dates and expiry.",
382
+ // Best practices
383
+ 'For progressive bracket taxes, ensure brackets are contiguous (each bracket starts where the previous ends) and the last bracket has "to: null" for uncapped top bracket.',
384
+ 'Use conditions (JSONLogic DSL) to restrict rules to specific taxpayer categories (e.g. revenue >= threshold, business type == "enterprise").',
385
+ "When multiple taxes apply to the same base, create separate rules for each \u2014 the engine evaluates all matching rules and produces a combined breakdown.",
386
+ "Always validate rules after creation to catch missing fields, invalid enums, and checksum mismatches."
387
+ ]
388
+ };
389
+
247
390
  // src/jurisdiction/ScopeResolver.ts
248
391
  var SCOPE_MULTIPLIER2 = {
249
392
  GLOBAL: 1,
@@ -324,6 +467,7 @@ export {
324
467
  ParamsValidator,
325
468
  ProgressiveBracketModel,
326
469
  ScopeResolver,
327
- ThresholdModel
470
+ ThresholdModel,
471
+ fiscalDescriptor
328
472
  };
329
473
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/FiscalPlugin.ts","../src/jurisdiction/JurisdictionResolver.ts","../src/models/FlatRateModel.ts","../src/models/ProgressiveBracketModel.ts","../src/models/MinimumTaxModel.ts","../src/models/ThresholdModel.ts","../src/models/FixedAmountModel.ts","../src/models/CompositeModel.ts","../src/jurisdiction/ScopeResolver.ts","../src/validators/FiscalRuleValidator.ts","../src/validators/ParamsValidator.ts"],"sourcesContent":["import { BasePlugin } from '@run-iq/plugin-sdk';\nimport type { EvaluationInput, EvaluationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { FiscalRule } from './types/fiscal-rule.js';\nimport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nimport { FlatRateModel } from './models/FlatRateModel.js';\nimport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nimport { ThresholdModel } from './models/ThresholdModel.js';\nimport { FixedAmountModel } from './models/FixedAmountModel.js';\nimport { CompositeModel } from './models/CompositeModel.js';\n\nexport class FiscalPlugin extends BasePlugin {\n readonly name = '@run-iq/plugin-fiscal' as const;\n readonly version = '0.1.0';\n\n readonly models: CalculationModel[] = [\n new FlatRateModel(),\n new ProgressiveBracketModel(),\n new MinimumTaxModel(),\n new ThresholdModel(),\n new FixedAmountModel(),\n new CompositeModel(),\n ];\n\n override beforeEvaluate(input: EvaluationInput, rules: ReadonlyArray<Rule>): EvaluationInput {\n const fiscalRules = rules as ReadonlyArray<FiscalRule>;\n\n // 1. Resolve priorities from jurisdiction + scope\n const resolvedRules = fiscalRules.map((rule) => ({\n ...rule,\n priority: JurisdictionResolver.resolve(rule.jurisdiction, rule.scope),\n }));\n\n // 2. Filter by country if provided in context\n const country = input.meta.context?.['country'] as string | undefined;\n const filteredRules = country\n ? resolvedRules.filter((r) => r.country === country)\n : resolvedRules;\n\n // IMMUTABLE — return new values\n return {\n ...input,\n data: {\n ...input.data,\n _resolvedRules: filteredRules,\n },\n };\n }\n\n override afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n // Enrich result with fiscal breakdown by category\n const fiscalBreakdown: Record<string, number> = {};\n\n for (const item of result.breakdown) {\n const rule = result.appliedRules.find((r) => r.id === item.ruleId) as FiscalRule | undefined;\n const category = rule?.category ?? 'unknown';\n fiscalBreakdown[category] = (fiscalBreakdown[category] ?? 0) + (item.contribution as number);\n }\n\n return {\n ...result,\n meta: { ...result.meta, fiscalBreakdown },\n };\n }\n}\n","import type { FiscalJurisdiction } from '../types/jurisdiction.js';\nimport type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst JURISDICTION_BASE: Record<FiscalJurisdiction, number> = {\n NATIONAL: 3000,\n REGIONAL: 2000,\n MUNICIPAL: 1000,\n};\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class JurisdictionResolver {\n static resolve(jurisdiction: FiscalJurisdiction, scope: FiscalScope): number {\n const base = JURISDICTION_BASE[jurisdiction];\n const multiplier = SCOPE_MULTIPLIER[scope];\n return Math.round(base * multiplier);\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FlatRateParams } from '../types/params.js';\n\nexport class FlatRateModel extends BaseModel {\n readonly name = 'FLAT_RATE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as FlatRateParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n return baseValue.mul(rate).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { BracketParams } from '../types/params.js';\n\nexport class ProgressiveBracketModel extends BaseModel {\n readonly name = 'PROGRESSIVE_BRACKET' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (typeof p['base'] !== 'string') {\n errors.push('\"base\" must be a string');\n }\n if (!Array.isArray(p['brackets']) || p['brackets'].length === 0) {\n errors.push('\"brackets\" must be a non-empty array');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as BracketParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n let total = new Decimal(0);\n\n for (const bracket of p.brackets) {\n const from = new Decimal(String(bracket.from));\n const to = bracket.to !== null ? new Decimal(String(bracket.to)) : null;\n const rate = new Decimal(String(bracket.rate));\n\n if (baseValue.lte(from)) {\n break;\n }\n\n const taxableInBracket =\n to !== null ? Decimal.min(baseValue, to).minus(from) : baseValue.minus(from);\n\n if (taxableInBracket.gt(0)) {\n total = total.plus(taxableInBracket.mul(rate));\n }\n }\n\n return total.toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { MinimumTaxParams } from '../types/params.js';\n\nexport class MinimumTaxModel extends BaseModel {\n readonly name = 'MINIMUM_TAX' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as MinimumTaxParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n const minimum = new Decimal(String(p.minimum));\n const computed = baseValue.mul(rate);\n return Decimal.max(computed, minimum).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { ThresholdParams } from '../types/params.js';\n\nexport class ThresholdModel extends BaseModel {\n readonly name = 'THRESHOLD_BASED' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as ThresholdParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const threshold = new Decimal(String(p.threshold));\n const rate = new Decimal(String(p.rate));\n\n if (baseValue.lte(threshold)) {\n return 0;\n }\n\n if (p.above_only) {\n return baseValue.minus(threshold).mul(rate).toNumber();\n }\n\n return baseValue.mul(rate).toNumber();\n }\n}\n","import { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FixedAmountParams } from '../types/params.js';\n\nexport class FixedAmountModel extends BaseModel {\n readonly name = 'FIXED_AMOUNT' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n\n calculate(\n _input: Record<string, unknown>,\n _matchedRule: Readonly<Rule>,\n params: unknown,\n ): number {\n const p = params as FixedAmountParams;\n return p.amount;\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { CompositeParams } from '../types/params.js';\nimport { FlatRateModel } from './FlatRateModel.js';\nimport { ProgressiveBracketModel } from './ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './MinimumTaxModel.js';\nimport { ThresholdModel } from './ThresholdModel.js';\nimport { FixedAmountModel } from './FixedAmountModel.js';\n\nconst SUB_MODELS: Record<string, CalculationModel> = {\n FLAT_RATE: new FlatRateModel(),\n PROGRESSIVE_BRACKET: new ProgressiveBracketModel(),\n MINIMUM_TAX: new MinimumTaxModel(),\n THRESHOLD_BASED: new ThresholdModel(),\n FIXED_AMOUNT: new FixedAmountModel(),\n};\n\nexport class CompositeModel extends BaseModel {\n readonly name = 'COMPOSITE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!Array.isArray(p['steps']) || p['steps'].length === 0) {\n errors.push('\"steps\" must be a non-empty array');\n }\n\n const agg = p['aggregation'];\n if (agg !== 'SUM' && agg !== 'MAX' && agg !== 'MIN') {\n errors.push('\"aggregation\" must be SUM, MAX, or MIN');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as CompositeParams;\n const contributions: Decimal[] = [];\n\n for (const step of p.steps) {\n const subModel = SUB_MODELS[step.model];\n if (!subModel) {\n continue;\n }\n const value = subModel.calculate(input, matchedRule, step.params);\n contributions.push(new Decimal(String(value)));\n }\n\n if (contributions.length === 0) {\n return 0;\n }\n\n switch (p.aggregation) {\n case 'SUM':\n return contributions.reduce((acc, v) => acc.plus(v), new Decimal(0)).toNumber();\n case 'MAX':\n return Decimal.max(...contributions).toNumber();\n case 'MIN':\n return Decimal.min(...contributions).toNumber();\n }\n }\n}\n","import type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class ScopeResolver {\n static getMultiplier(scope: FiscalScope): number {\n return SCOPE_MULTIPLIER[scope];\n }\n}\n","import type { FiscalRule } from '../types/fiscal-rule.js';\n\nconst VALID_JURISDICTIONS = ['NATIONAL', 'REGIONAL', 'MUNICIPAL'];\nconst VALID_SCOPES = ['GLOBAL', 'ORGANIZATION', 'USER'];\n\nexport class FiscalRuleValidator {\n static validate(rule: unknown): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n if (rule === null || typeof rule !== 'object') {\n return { valid: false, errors: ['rule must be an object'] };\n }\n\n const r = rule as Partial<FiscalRule>;\n\n if (!r.jurisdiction || !VALID_JURISDICTIONS.includes(r.jurisdiction)) {\n errors.push(`jurisdiction must be one of: ${VALID_JURISDICTIONS.join(', ')}`);\n }\n if (!r.scope || !VALID_SCOPES.includes(r.scope)) {\n errors.push(`scope must be one of: ${VALID_SCOPES.join(', ')}`);\n }\n if (typeof r.country !== 'string' || r.country.length === 0) {\n errors.push('country must be a non-empty string');\n }\n if (typeof r.category !== 'string' || r.category.length === 0) {\n errors.push('category must be a non-empty string');\n }\n\n return { valid: errors.length === 0, errors };\n }\n}\n","import { SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult } from '@run-iq/core';\n\nexport class ParamsValidator {\n static validateFlatRate(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n static validateMinimumTax(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n static validateThreshold(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n static validateFixedAmount(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n}\n"],"mappings":"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","names":["Decimal","BaseModel","Decimal","BaseModel","SchemaValidator","Decimal","BaseModel","SchemaValidator","BaseModel","SchemaValidator","Decimal","BaseModel","BaseModel","Decimal","SCOPE_MULTIPLIER","SchemaValidator"]}
1
+ {"version":3,"sources":["../src/FiscalPlugin.ts","../src/jurisdiction/JurisdictionResolver.ts","../src/models/FlatRateModel.ts","../src/models/ProgressiveBracketModel.ts","../src/models/MinimumTaxModel.ts","../src/models/ThresholdModel.ts","../src/models/FixedAmountModel.ts","../src/models/CompositeModel.ts","../src/descriptor.ts","../src/jurisdiction/ScopeResolver.ts","../src/validators/FiscalRuleValidator.ts","../src/validators/ParamsValidator.ts"],"sourcesContent":["import { BasePlugin } from '@run-iq/plugin-sdk';\nimport type { EvaluationInput, EvaluationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { FiscalRule } from './types/fiscal-rule.js';\nimport { JurisdictionResolver } from './jurisdiction/JurisdictionResolver.js';\nimport { FlatRateModel } from './models/FlatRateModel.js';\nimport { ProgressiveBracketModel } from './models/ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './models/MinimumTaxModel.js';\nimport { ThresholdModel } from './models/ThresholdModel.js';\nimport { FixedAmountModel } from './models/FixedAmountModel.js';\nimport { CompositeModel } from './models/CompositeModel.js';\n\nexport class FiscalPlugin extends BasePlugin {\n readonly name = '@run-iq/plugin-fiscal' as const;\n readonly version = '0.1.0';\n\n readonly models: CalculationModel[] = [\n new FlatRateModel(),\n new ProgressiveBracketModel(),\n new MinimumTaxModel(),\n new ThresholdModel(),\n new FixedAmountModel(),\n new CompositeModel(),\n ];\n\n override beforeEvaluate(input: EvaluationInput, rules: ReadonlyArray<Rule>): EvaluationInput {\n const fiscalRules = rules as ReadonlyArray<FiscalRule>;\n\n // 1. Resolve priorities from jurisdiction + scope\n const resolvedRules = fiscalRules.map((rule) => ({\n ...rule,\n priority: JurisdictionResolver.resolve(rule.jurisdiction, rule.scope),\n }));\n\n // 2. Filter by country if provided in context\n const country = input.meta.context?.['country'] as string | undefined;\n const filteredRules = country\n ? resolvedRules.filter((r) => r.country === country)\n : resolvedRules;\n\n // IMMUTABLE — return new values\n return {\n ...input,\n data: {\n ...input.data,\n _resolvedRules: filteredRules,\n },\n };\n }\n\n override afterEvaluate(_input: EvaluationInput, result: EvaluationResult): EvaluationResult {\n // Enrich result with fiscal breakdown by category\n const fiscalBreakdown: Record<string, number> = {};\n\n for (const item of result.breakdown) {\n const rule = result.appliedRules.find((r) => r.id === item.ruleId) as FiscalRule | undefined;\n const category = rule?.category ?? 'unknown';\n fiscalBreakdown[category] = (fiscalBreakdown[category] ?? 0) + (item.contribution as number);\n }\n\n return {\n ...result,\n meta: { ...result.meta, fiscalBreakdown },\n };\n }\n}\n","import type { FiscalJurisdiction } from '../types/jurisdiction.js';\nimport type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst JURISDICTION_BASE: Record<FiscalJurisdiction, number> = {\n NATIONAL: 3000,\n REGIONAL: 2000,\n MUNICIPAL: 1000,\n};\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class JurisdictionResolver {\n static resolve(jurisdiction: FiscalJurisdiction, scope: FiscalScope): number {\n const base = JURISDICTION_BASE[jurisdiction];\n const multiplier = SCOPE_MULTIPLIER[scope];\n return Math.round(base * multiplier);\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FlatRateParams } from '../types/params.js';\n\nexport class FlatRateModel extends BaseModel {\n readonly name = 'FLAT_RATE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as FlatRateParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n return baseValue.mul(rate).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { BracketParams } from '../types/params.js';\n\nexport class ProgressiveBracketModel extends BaseModel {\n readonly name = 'PROGRESSIVE_BRACKET' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (typeof p['base'] !== 'string') {\n errors.push('\"base\" must be a string');\n }\n if (!Array.isArray(p['brackets']) || p['brackets'].length === 0) {\n errors.push('\"brackets\" must be a non-empty array');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as BracketParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n let total = new Decimal(0);\n\n for (const bracket of p.brackets) {\n const from = new Decimal(String(bracket.from));\n const to = bracket.to !== null ? new Decimal(String(bracket.to)) : null;\n const rate = new Decimal(String(bracket.rate));\n\n if (baseValue.lte(from)) {\n break;\n }\n\n const taxableInBracket =\n to !== null ? Decimal.min(baseValue, to).minus(from) : baseValue.minus(from);\n\n if (taxableInBracket.gt(0)) {\n total = total.plus(taxableInBracket.mul(rate));\n }\n }\n\n return total.toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { MinimumTaxParams } from '../types/params.js';\n\nexport class MinimumTaxModel extends BaseModel {\n readonly name = 'MINIMUM_TAX' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as MinimumTaxParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const rate = new Decimal(String(p.rate));\n const minimum = new Decimal(String(p.minimum));\n const computed = baseValue.mul(rate);\n return Decimal.max(computed, minimum).toNumber();\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { ThresholdParams } from '../types/params.js';\n\nexport class ThresholdModel extends BaseModel {\n readonly name = 'THRESHOLD_BASED' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n calculate(input: Record<string, unknown>, _matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as ThresholdParams;\n const baseValue = new Decimal(String(input[p.base] ?? 0));\n const threshold = new Decimal(String(p.threshold));\n const rate = new Decimal(String(p.rate));\n\n if (baseValue.lte(threshold)) {\n return 0;\n }\n\n if (p.above_only) {\n return baseValue.minus(threshold).mul(rate).toNumber();\n }\n\n return baseValue.mul(rate).toNumber();\n }\n}\n","import { BaseModel, SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule } from '@run-iq/core';\nimport type { FixedAmountParams } from '../types/params.js';\n\nexport class FixedAmountModel extends BaseModel {\n readonly name = 'FIXED_AMOUNT' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n\n calculate(\n _input: Record<string, unknown>,\n _matchedRule: Readonly<Rule>,\n params: unknown,\n ): number {\n const p = params as FixedAmountParams;\n return p.amount;\n }\n}\n","import Decimal from 'decimal.js';\nimport { BaseModel } from '@run-iq/plugin-sdk';\nimport type { ValidationResult, Rule, CalculationModel } from '@run-iq/core';\nimport type { CompositeParams } from '../types/params.js';\nimport { FlatRateModel } from './FlatRateModel.js';\nimport { ProgressiveBracketModel } from './ProgressiveBracketModel.js';\nimport { MinimumTaxModel } from './MinimumTaxModel.js';\nimport { ThresholdModel } from './ThresholdModel.js';\nimport { FixedAmountModel } from './FixedAmountModel.js';\n\nconst SUB_MODELS: Record<string, CalculationModel> = {\n FLAT_RATE: new FlatRateModel(),\n PROGRESSIVE_BRACKET: new ProgressiveBracketModel(),\n MINIMUM_TAX: new MinimumTaxModel(),\n THRESHOLD_BASED: new ThresholdModel(),\n FIXED_AMOUNT: new FixedAmountModel(),\n};\n\nexport class CompositeModel extends BaseModel {\n readonly name = 'COMPOSITE' as const;\n readonly version = '1.0.0';\n\n validateParams(params: unknown): ValidationResult {\n if (params === null || typeof params !== 'object') {\n return { valid: false, errors: ['params must be an object'] };\n }\n const p = params as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!Array.isArray(p['steps']) || p['steps'].length === 0) {\n errors.push('\"steps\" must be a non-empty array');\n }\n\n const agg = p['aggregation'];\n if (agg !== 'SUM' && agg !== 'MAX' && agg !== 'MIN') {\n errors.push('\"aggregation\" must be SUM, MAX, or MIN');\n }\n\n return errors.length > 0 ? { valid: false, errors } : { valid: true };\n }\n\n calculate(input: Record<string, unknown>, matchedRule: Readonly<Rule>, params: unknown): number {\n const p = params as CompositeParams;\n const contributions: Decimal[] = [];\n\n for (const step of p.steps) {\n const subModel = SUB_MODELS[step.model];\n if (!subModel) {\n continue;\n }\n const value = subModel.calculate(input, matchedRule, step.params);\n contributions.push(new Decimal(String(value)));\n }\n\n if (contributions.length === 0) {\n return 0;\n }\n\n switch (p.aggregation) {\n case 'SUM':\n return contributions.reduce((acc, v) => acc.plus(v), new Decimal(0)).toNumber();\n case 'MAX':\n return Decimal.max(...contributions).toNumber();\n case 'MIN':\n return Decimal.min(...contributions).toNumber();\n }\n }\n}\n","import type { PluginDescriptor } from '@run-iq/plugin-sdk';\n\nexport const fiscalDescriptor: PluginDescriptor = {\n name: '@run-iq/plugin-fiscal',\n version: '0.1.0',\n domainLabel: 'fiscal',\n description:\n 'Fiscal domain plugin for tax calculation. Provides 6 universal calculation models applicable to any tax system worldwide: flat rates (VAT/GST/Sales Tax), progressive brackets (income tax), minimum tax floors, threshold-based taxes, fixed levies, and composite multi-step calculations.',\n\n ruleExtensions: [\n {\n name: 'jurisdiction',\n type: 'string',\n required: true,\n description:\n 'Tax jurisdiction level. Determines rule priority: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). National laws override regional, which override municipal.',\n enum: ['NATIONAL', 'REGIONAL', 'MUNICIPAL'],\n },\n {\n name: 'scope',\n type: 'string',\n required: true,\n description:\n 'Rule application scope. Refines priority within a jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). More specific scope wins over general.',\n enum: ['GLOBAL', 'ORGANIZATION', 'USER'],\n },\n {\n name: 'country',\n type: 'string',\n required: true,\n description:\n 'ISO 3166-1 alpha-2 country code (e.g. \"TG\" for Togo, \"FR\" for France, \"US\" for United States, \"IN\" for India). Rules are filtered by country at evaluation time via input.meta.context.country.',\n },\n {\n name: 'category',\n type: 'string',\n required: true,\n description:\n 'Tax category identifier for grouping in fiscal breakdown. Common values: \"TVA\" (VAT), \"IRPP\" (income tax), \"IS\" (corporate tax), \"IMF\" (minimum tax), \"GST\", \"SALES_TAX\". Free-form string — use consistent naming per tax system.',\n },\n ],\n\n inputFields: [\n {\n name: 'revenue',\n type: 'number',\n description:\n \"Business revenue / turnover (chiffre d'affaires). Used as base for VAT, corporate tax, minimum tax.\",\n examples: [1_000_000, 5_000_000, 50_000_000],\n },\n {\n name: 'income',\n type: 'number',\n description:\n 'Taxable income (revenu imposable). Used as base for progressive income tax brackets.',\n examples: [500_000, 2_000_000, 10_000_000],\n },\n {\n name: 'expenses',\n type: 'number',\n description: 'Deductible expenses. Can be used in conditions or composite calculations.',\n examples: [200_000, 1_000_000],\n },\n {\n name: 'netProfit',\n type: 'number',\n description: 'Net profit (benefice net). Used as base for corporate income tax.',\n examples: [300_000, 5_000_000],\n },\n ],\n\n examples: [\n {\n title: 'VAT / TVA — Flat Rate',\n description:\n 'Value-added tax at a flat rate on revenue. Applicable to any country (adjust rate and country code).',\n rule: {\n id: 'tg-tva-18',\n model: 'FLAT_RATE',\n params: { rate: 0.18, base: 'revenue' },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'TVA',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['tva', 'vat'],\n },\n input: { revenue: 1_000_000 },\n },\n {\n title: 'Income Tax — Progressive Brackets',\n description:\n 'Progressive income tax with cumulative brackets. Each bracket applies its rate only to the portion of income within its range.',\n rule: {\n id: 'tg-irpp-2025',\n model: 'PROGRESSIVE_BRACKET',\n params: {\n base: 'income',\n brackets: [\n { from: 0, to: 500_000, rate: 0 },\n { from: 500_000, to: 1_000_000, rate: 0.1 },\n { from: 1_000_000, to: 3_000_000, rate: 0.15 },\n { from: 3_000_000, to: 5_000_000, rate: 0.25 },\n { from: 5_000_000, to: null, rate: 0.35 },\n ],\n },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'IRPP',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['irpp', 'income-tax'],\n },\n input: { income: 2_000_000 },\n },\n {\n title: 'Minimum Tax Floor',\n description:\n 'Minimum tax: MAX(base * rate, fixed minimum). Ensures a minimum tax amount regardless of the proportional calculation.',\n rule: {\n id: 'tg-imf-2025',\n model: 'MINIMUM_TAX',\n params: { rate: 0.01, base: 'revenue', minimum: 50_000 },\n jurisdiction: 'NATIONAL',\n scope: 'GLOBAL',\n country: 'TG',\n category: 'IMF',\n effectiveFrom: '2025-01-01T00:00:00.000Z',\n effectiveUntil: null,\n tags: ['imf', 'minimum-tax'],\n },\n input: { revenue: 3_000_000 },\n },\n ],\n\n promptGuidelines: [\n // Domain universality\n 'This plugin provides universal tax calculation models applicable to ANY tax system worldwide — not limited to any specific country or legal framework.',\n 'Always specify the correct ISO 3166-1 alpha-2 country code — rules are filtered by country at evaluation time.',\n\n // Model selection\n 'Choose the right model for each tax type: FLAT_RATE for proportional taxes (VAT/TVA/GST/Sales Tax), PROGRESSIVE_BRACKET for income tax with cumulative brackets, MINIMUM_TAX for minimum tax floors (MAX of proportional and fixed amount), THRESHOLD for taxes that only apply above a threshold, FIXED_AMOUNT for fixed levies regardless of base, COMPOSITE for multi-step calculations combining sub-models (SUM/MAX/MIN).',\n\n // Jurisdiction & scope\n 'Jurisdiction determines rule priority hierarchy: NATIONAL (3000) > REGIONAL (2000) > MUNICIPAL (1000). When rules conflict, higher jurisdiction wins.',\n 'Scope refines priority within the same jurisdiction: USER (x1.2) > ORGANIZATION (x1.1) > GLOBAL (x1.0). A user-specific rule overrides an organization-wide rule at the same jurisdiction level.',\n\n // Category & breakdown\n 'Use the category field consistently to group related taxes (e.g. \"TVA\", \"IRPP\", \"IS\"). The afterEvaluate hook produces a fiscal breakdown grouped by category — inconsistent naming breaks grouping.',\n\n // Analyzing tax legislation\n 'When analyzing tax legislation, identify: (1) the tax base — what amount is being taxed (revenue, income, profit), (2) the rate structure — flat rate, progressive brackets, minimum floor, (3) any thresholds or exemptions, (4) the jurisdiction level and applicable scope, (5) effective dates and expiry.',\n\n // Best practices\n 'For progressive bracket taxes, ensure brackets are contiguous (each bracket starts where the previous ends) and the last bracket has \"to: null\" for uncapped top bracket.',\n 'Use conditions (JSONLogic DSL) to restrict rules to specific taxpayer categories (e.g. revenue >= threshold, business type == \"enterprise\").',\n 'When multiple taxes apply to the same base, create separate rules for each — the engine evaluates all matching rules and produces a combined breakdown.',\n 'Always validate rules after creation to catch missing fields, invalid enums, and checksum mismatches.',\n ],\n};\n","import type { FiscalScope } from '../types/fiscal-rule.js';\n\nconst SCOPE_MULTIPLIER: Record<FiscalScope, number> = {\n GLOBAL: 1.0,\n ORGANIZATION: 1.1,\n USER: 1.2,\n};\n\nexport class ScopeResolver {\n static getMultiplier(scope: FiscalScope): number {\n return SCOPE_MULTIPLIER[scope];\n }\n}\n","import type { FiscalRule } from '../types/fiscal-rule.js';\n\nconst VALID_JURISDICTIONS = ['NATIONAL', 'REGIONAL', 'MUNICIPAL'];\nconst VALID_SCOPES = ['GLOBAL', 'ORGANIZATION', 'USER'];\n\nexport class FiscalRuleValidator {\n static validate(rule: unknown): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n if (rule === null || typeof rule !== 'object') {\n return { valid: false, errors: ['rule must be an object'] };\n }\n\n const r = rule as Partial<FiscalRule>;\n\n if (!r.jurisdiction || !VALID_JURISDICTIONS.includes(r.jurisdiction)) {\n errors.push(`jurisdiction must be one of: ${VALID_JURISDICTIONS.join(', ')}`);\n }\n if (!r.scope || !VALID_SCOPES.includes(r.scope)) {\n errors.push(`scope must be one of: ${VALID_SCOPES.join(', ')}`);\n }\n if (typeof r.country !== 'string' || r.country.length === 0) {\n errors.push('country must be a non-empty string');\n }\n if (typeof r.category !== 'string' || r.category.length === 0) {\n errors.push('category must be a non-empty string');\n }\n\n return { valid: errors.length === 0, errors };\n }\n}\n","import { SchemaValidator } from '@run-iq/plugin-sdk';\nimport type { ValidationResult } from '@run-iq/core';\n\nexport class ParamsValidator {\n static validateFlatRate(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n });\n }\n\n static validateMinimumTax(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n rate: { type: 'number', min: 0, max: 1 },\n base: { type: 'string' },\n minimum: { type: 'number', min: 0 },\n });\n }\n\n static validateThreshold(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n base: { type: 'string' },\n threshold: { type: 'number', min: 0 },\n rate: { type: 'number', min: 0, max: 1 },\n above_only: { type: 'boolean' },\n });\n }\n\n static validateFixedAmount(params: unknown): ValidationResult {\n return SchemaValidator.validate(params, {\n amount: { type: 'number', min: 0 },\n currency: { type: 'string' },\n });\n }\n}\n"],"mappings":"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","names":["Decimal","BaseModel","Decimal","BaseModel","SchemaValidator","Decimal","BaseModel","SchemaValidator","BaseModel","SchemaValidator","Decimal","BaseModel","BaseModel","Decimal","SCOPE_MULTIPLIER","SchemaValidator"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@run-iq/plugin-fiscal",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Fiscal domain plugin for PPE — tax calculation models",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -28,7 +28,7 @@
28
28
  },
29
29
  "peerDependencies": {
30
30
  "@run-iq/core": "^0.1.0",
31
- "@run-iq/plugin-sdk": "^0.1.0"
31
+ "@run-iq/plugin-sdk": "^0.2.0"
32
32
  },
33
33
  "dependencies": {
34
34
  "decimal.js": "^10.4.3"
@@ -44,6 +44,14 @@
44
44
  "typescript": "^5.4.0",
45
45
  "vitest": "^1.3.0"
46
46
  },
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "https://github.com/Run-IQ/plugin-fiscal.git"
50
+ },
51
+ "homepage": "https://github.com/Run-IQ/plugin-fiscal#readme",
52
+ "bugs": {
53
+ "url": "https://github.com/Run-IQ/plugin-fiscal/issues"
54
+ },
47
55
  "author": "Abdou-Raouf ATARMLA",
48
56
  "license": "SEE LICENSE IN LICENSE",
49
57
  "engines": {