Skip to content
SlashClone
Made by@dealdesk

Discount approval check

@dealdesk/discount-approval-check

Check a deal against your own approval policy file and get the list of who must approve and why: discount ladders, payment terms, billing frequency, term length, free months, non-standard terms, and deal size. Also shows how much room is left before the next approval.

SkillRevOpsv1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1{
  2. 2 "name": "discount-approval-check",
  3. 3 "owner": "dealdesk",
  4. 4 "version": "1.0.0",
  5. 5 "type": "skill",
  6. 6 "description": "Check a deal against your own approval policy file and get the list of who must approve and why: discount ladders, payment terms, billing frequency, term length, free months, non-standard terms, and deal size. Also shows how much room is left before the next approval.",
  7. 7 "category": "revops",
  8. 8 "license": "MIT",
  9. 9 "compat": [
  10. 10 "claude-code"
  11. 11 ],
  12. 12 "permissions": {
  13. 13 "shell": [
  14. 14 "node scripts/approvals.mjs"
  15. 15 ],
  16. 16 "files": {
  17. 17 "read": [
  18. 18 "./data/**"
  19. 19 ],
  20. 20 "write": [
  21. 21 "./data/**",
  22. 22 "./out/**"
  23. 23 ]
  24. 24 }
  25. 25 },
  26. 26 "tests": {
  27. 27 "cases": [
  28. 28 {
  29. 29 "name": "discount ladder keeps only the highest step, plus finance and legal",
  30. 30 "inputs": {
  31. 31 "data/policy.json": "{\"approvers\":[\"Sales manager\",\"VP Sales\",\"Finance\",\"Legal\",\"CFO\"],\"rules\":[{\"id\":\"d15\",\"group\":\"discount\",\"when\":[{\"metric\":\"discount_pct\",\"op\":\">\",\"value\":15}],\"approver\":\"Sales manager\"},{\"id\":\"d25\",\"group\":\"discount\",\"when\":[{\"metric\":\"discount_pct\",\"op\":\">\",\"value\":25}],\"approver\":\"VP Sales\"},{\"id\":\"d40\",\"group\":\"discount\",\"when\":[{\"metric\":\"discount_pct\",\"op\":\">\",\"value\":40}],\"approver\":\"CFO\"},{\"id\":\"terms\",\"when\":[{\"metric\":\"payment_terms_days\",\"op\":\">\",\"value\":30}],\"approver\":\"Finance\"},{\"id\":\"legal\",\"when\":[{\"metric\":\"nonstandard_terms\",\"op\":\">\",\"value\":0}],\"approver\":\"Legal\"},{\"id\":\"mfn\",\"when\":[{\"metric\":\"mfn\",\"op\":\"is_true\"}],\"approver\":\"CFO\"}]}",
  32. 32 "data/deal.json": "{\"customer\":{\"legal_name\":\"Northwind Traders LLC\"},\"term_months\":24,\"payment_terms\":\"Net 45\",\"nonstandard_terms\":[\"Termination for convenience\"],\"lines\":[{\"sku\":\"PLAT-SEAT\",\"quantity\":60,\"list_price\":600,\"net_price\":420},{\"sku\":\"SUP-PREM\",\"quantity\":1,\"list_price\":6000,\"net_price\":6000},{\"sku\":\"ONB-STD\",\"quantity\":1,\"list_price\":5000,\"net_price\":2500,\"billing\":\"one_time\"}]}"
  33. 33 },
  34. 34 "checks": [
  35. 35 {
  36. 36 "type": "command_exits_zero",
  37. 37 "command": "node scripts/approvals.mjs data/deal.json data/policy.json --out out"
  38. 38 },
  39. 39 {
  40. 40 "type": "output_matches_schema",
  41. 41 "path": "out/approvals.json",
  42. 42 "schema": {
  43. 43 "type": "object",
  44. 44 "required": [
  45. 45 "status",
  46. 46 "approvals",
  47. 47 "metrics",
  48. 48 "could_not_check"
  49. 49 ],
  50. 50 "properties": {
  51. 51 "status": {
  52. 52 "const": "needs_approval"
  53. 53 },
  54. 54 "approver_count": {
  55. 55 "const": 3
  56. 56 },
  57. 57 "superseded_rules": {
  58. 58 "const": [
  59. 59 "d15"
  60. 60 ]
  61. 61 },
  62. 62 "metrics": {
  63. 63 "type": "object",
  64. 64 "properties": {
  65. 65 "discount_pct": {
  66. 66 "const": 27.1
  67. 67 },
  68. 68 "payment_terms_days": {
  69. 69 "const": 45
  70. 70 }
  71. 71 }
  72. 72 },
  73. 73 "could_not_check": {
  74. 74 "type": "array",
  75. 75 "minItems": 1,
  76. 76 "maxItems": 1
  77. 77 },
  78. 78 "approvals": {
  79. 79 "type": "array",
  80. 80 "minItems": 3,
  81. 81 "maxItems": 3,
  82. 82 "items": {
  83. 83 "type": "object",
  84. 84 "properties": {
  85. 85 "approver": {
  86. 86 "enum": [
  87. 87 "VP Sales",
  88. 88 "Finance",
  89. 89 "Legal"
  90. 90 ]
  91. 91 }
  92. 92 }
  93. 93 }
  94. 94 }
  95. 95 }
  96. 96 }
  97. 97 }
  98. 98 ]
  99. 99 },
  100. 100 {
  101. 101 "name": "a clean deal is auto-approved",
  102. 102 "inputs": {
  103. 103 "data/policy.json": "{\"rules\":[{\"id\":\"d15\",\"when\":[{\"metric\":\"discount_pct\",\"op\":\">\",\"value\":15}],\"approver\":\"Sales manager\"},{\"id\":\"terms\",\"when\":[{\"metric\":\"payment_terms_days\",\"op\":\">\",\"value\":30}],\"approver\":\"Finance\"}]}",
  104. 104 "data/deal.json": "{\"payment_terms\":\"Net 30\",\"lines\":[{\"sku\":\"A\",\"quantity\":10,\"list_price\":100,\"net_price\":90}]}"
  105. 105 },
  106. 106 "checks": [
  107. 107 {
  108. 108 "type": "command_exits_zero",
  109. 109 "command": "node scripts/approvals.mjs data/deal.json data/policy.json --out out"
  110. 110 },
  111. 111 {
  112. 112 "type": "file_contains",
  113. 113 "path": "out/approvals.md",
  114. 114 "text": "**Within policy.** No approvals needed."
  115. 115 },
  116. 116 {
  117. 117 "type": "output_matches_schema",
  118. 118 "path": "out/approvals.json",
  119. 119 "schema": {
  120. 120 "type": "object",
  121. 121 "properties": {
  122. 122 "status": {
  123. 123 "const": "auto_approved"
  124. 124 },
  125. 125 "approver_count": {
  126. 126 "const": 0
  127. 127 }
  128. 128 }
  129. 129 }
  130. 130 }
  131. 131 ]
  132. 132 }
  133. 133 ]
  134. 134 }