@tailor-platform/erp-kit 0.0.1 → 0.1.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.
Files changed (213) hide show
  1. package/README.md +196 -28
  2. package/dist/cli.js +894 -0
  3. package/package.json +65 -8
  4. package/rules/app-compose/backend/auth.md +78 -0
  5. package/rules/app-compose/frontend/auth.md +55 -0
  6. package/rules/app-compose/frontend/component.md +55 -0
  7. package/rules/app-compose/frontend/page.md +86 -0
  8. package/rules/app-compose/frontend/screen-detailview.md +112 -0
  9. package/rules/app-compose/frontend/screen-form.md +145 -0
  10. package/rules/app-compose/frontend/screen-listview.md +159 -0
  11. package/rules/app-compose/structure.md +32 -0
  12. package/rules/module-development/commands.md +54 -0
  13. package/rules/module-development/cross-module-type-injection.md +28 -0
  14. package/rules/module-development/dependency-modules.md +24 -0
  15. package/rules/module-development/errors.md +12 -0
  16. package/rules/module-development/executors.md +67 -0
  17. package/rules/module-development/exports.md +13 -0
  18. package/rules/module-development/models.md +34 -0
  19. package/rules/module-development/structure.md +27 -0
  20. package/rules/module-development/sync-vs-async-operations.md +83 -0
  21. package/rules/module-development/testing.md +43 -0
  22. package/rules/sdk-best-practices/db-relations.md +74 -0
  23. package/rules/sdk-best-practices/sdk-docs.md +14 -0
  24. package/schemas/app-compose/actors.yml +34 -0
  25. package/schemas/app-compose/business-flow.yml +50 -0
  26. package/schemas/app-compose/requirements.yml +33 -0
  27. package/schemas/app-compose/resolver.yml +47 -0
  28. package/schemas/app-compose/screen.yml +81 -0
  29. package/schemas/app-compose/story.yml +67 -0
  30. package/schemas/module/command.yml +52 -0
  31. package/schemas/module/feature.yml +58 -0
  32. package/schemas/module/model.yml +70 -0
  33. package/schemas/module/module.yml +50 -0
  34. package/skills/1-module-docs/SKILL.md +107 -0
  35. package/skills/2-module-feature-breakdown/SKILL.md +66 -0
  36. package/skills/3-module-doc-review/SKILL.md +230 -0
  37. package/skills/4-module-tdd-implementation/SKILL.md +56 -0
  38. package/skills/5-module-implementation-review/SKILL.md +400 -0
  39. package/skills/app-compose-1-requirement-analysis/SKILL.md +85 -0
  40. package/skills/app-compose-2-requirements-breakdown/SKILL.md +88 -0
  41. package/skills/app-compose-3-doc-review/SKILL.md +112 -0
  42. package/skills/app-compose-4-design-mock/SKILL.md +248 -0
  43. package/skills/app-compose-5-design-mock-review/SKILL.md +283 -0
  44. package/skills/app-compose-6-implementation-spec/SKILL.md +122 -0
  45. package/skills/mock-scenario/SKILL.md +118 -0
  46. package/src/app.ts +1 -0
  47. package/src/cli.ts +120 -0
  48. package/src/commands/check.test.ts +30 -0
  49. package/src/commands/check.ts +66 -0
  50. package/src/commands/init.test.ts +77 -0
  51. package/src/commands/init.ts +87 -0
  52. package/src/commands/mock/index.ts +53 -0
  53. package/src/commands/mock/start.ts +179 -0
  54. package/src/commands/mock/validate.test.ts +185 -0
  55. package/src/commands/mock/validate.ts +198 -0
  56. package/src/commands/scaffold.test.ts +76 -0
  57. package/src/commands/scaffold.ts +119 -0
  58. package/src/commands/sync-check.test.ts +125 -0
  59. package/src/commands/sync-check.ts +182 -0
  60. package/src/integration.test.ts +63 -0
  61. package/src/mdschema.ts +48 -0
  62. package/src/mockServer.ts +55 -0
  63. package/src/module.ts +86 -0
  64. package/src/modules/accounting/.gitkeep +0 -0
  65. package/src/modules/coa-management/.gitkeep +0 -0
  66. package/src/modules/inventory/.gitkeep +0 -0
  67. package/src/modules/manufacturing/.gitkeep +0 -0
  68. package/src/modules/primitives/README.md +39 -0
  69. package/src/modules/primitives/command/activateCategory.test.ts +75 -0
  70. package/src/modules/primitives/command/activateCategory.ts +50 -0
  71. package/src/modules/primitives/command/activateCurrency.test.ts +70 -0
  72. package/src/modules/primitives/command/activateCurrency.ts +50 -0
  73. package/src/modules/primitives/command/activateUnit.test.ts +53 -0
  74. package/src/modules/primitives/command/activateUnit.ts +50 -0
  75. package/src/modules/primitives/command/convertAmount.test.ts +275 -0
  76. package/src/modules/primitives/command/convertAmount.ts +126 -0
  77. package/src/modules/primitives/command/convertQuantity.test.ts +219 -0
  78. package/src/modules/primitives/command/convertQuantity.ts +73 -0
  79. package/src/modules/primitives/command/createCategory.test.ts +126 -0
  80. package/src/modules/primitives/command/createCategory.ts +89 -0
  81. package/src/modules/primitives/command/createCurrency.test.ts +191 -0
  82. package/src/modules/primitives/command/createCurrency.ts +77 -0
  83. package/src/modules/primitives/command/createExchangeRate.test.ts +216 -0
  84. package/src/modules/primitives/command/createExchangeRate.ts +91 -0
  85. package/src/modules/primitives/command/createUnit.test.ts +214 -0
  86. package/src/modules/primitives/command/createUnit.ts +88 -0
  87. package/src/modules/primitives/command/deactivateCategory.test.ts +97 -0
  88. package/src/modules/primitives/command/deactivateCategory.ts +62 -0
  89. package/src/modules/primitives/command/deactivateCurrency.test.ts +85 -0
  90. package/src/modules/primitives/command/deactivateCurrency.ts +55 -0
  91. package/src/modules/primitives/command/deactivateUnit.test.ts +78 -0
  92. package/src/modules/primitives/command/deactivateUnit.ts +62 -0
  93. package/src/modules/primitives/command/setBaseCurrency.test.ts +98 -0
  94. package/src/modules/primitives/command/setBaseCurrency.ts +74 -0
  95. package/src/modules/primitives/command/setReferenceUnit.test.ts +108 -0
  96. package/src/modules/primitives/command/setReferenceUnit.ts +84 -0
  97. package/src/modules/primitives/db/currency.ts +30 -0
  98. package/src/modules/primitives/db/exchangeRate.ts +28 -0
  99. package/src/modules/primitives/db/unit.ts +32 -0
  100. package/src/modules/primitives/db/uomCategory.ts +32 -0
  101. package/src/modules/primitives/docs/commands/ActivateCategory.md +34 -0
  102. package/src/modules/primitives/docs/commands/ActivateCurrency.md +33 -0
  103. package/src/modules/primitives/docs/commands/ActivateUnit.md +34 -0
  104. package/src/modules/primitives/docs/commands/ConvertAmount.md +50 -0
  105. package/src/modules/primitives/docs/commands/ConvertQuantity.md +43 -0
  106. package/src/modules/primitives/docs/commands/CreateCategory.md +44 -0
  107. package/src/modules/primitives/docs/commands/CreateCurrency.md +47 -0
  108. package/src/modules/primitives/docs/commands/CreateExchangeRate.md +48 -0
  109. package/src/modules/primitives/docs/commands/CreateUnit.md +48 -0
  110. package/src/modules/primitives/docs/commands/DeactivateCategory.md +38 -0
  111. package/src/modules/primitives/docs/commands/DeactivateCurrency.md +38 -0
  112. package/src/modules/primitives/docs/commands/DeactivateUnit.md +38 -0
  113. package/src/modules/primitives/docs/commands/SetBaseCurrency.md +39 -0
  114. package/src/modules/primitives/docs/commands/SetReferenceUnit.md +43 -0
  115. package/src/modules/primitives/docs/features/currency-definitions.md +55 -0
  116. package/src/modules/primitives/docs/features/exchange-rates.md +61 -0
  117. package/src/modules/primitives/docs/features/unit-conversion.md +66 -0
  118. package/src/modules/primitives/docs/features/uom-categories.md +52 -0
  119. package/src/modules/primitives/docs/models/Currency.md +45 -0
  120. package/src/modules/primitives/docs/models/ExchangeRate.md +33 -0
  121. package/src/modules/primitives/docs/models/Unit.md +46 -0
  122. package/src/modules/primitives/docs/models/UoMCategory.md +44 -0
  123. package/src/modules/primitives/generated/kysely-tailordb.ts +95 -0
  124. package/src/modules/primitives/index.ts +40 -0
  125. package/src/modules/primitives/lib/errors.ts +138 -0
  126. package/src/modules/primitives/lib/types.ts +20 -0
  127. package/src/modules/primitives/module.ts +66 -0
  128. package/src/modules/primitives/permissions.ts +18 -0
  129. package/src/modules/primitives/tailor.config.ts +11 -0
  130. package/src/modules/primitives/testing/fixtures.ts +161 -0
  131. package/src/modules/product-management/.gitkeep +0 -0
  132. package/src/modules/purchase/.gitkeep +0 -0
  133. package/src/modules/sales/.gitkeep +0 -0
  134. package/src/modules/shared/createContext.test.ts +39 -0
  135. package/src/modules/shared/createContext.ts +15 -0
  136. package/src/modules/shared/defineCommand.test.ts +42 -0
  137. package/src/modules/shared/defineCommand.ts +19 -0
  138. package/src/modules/shared/definePermissions.test.ts +146 -0
  139. package/src/modules/shared/definePermissions.ts +94 -0
  140. package/src/modules/shared/entityTypes.ts +15 -0
  141. package/src/modules/shared/errors.ts +22 -0
  142. package/src/modules/shared/index.ts +1 -0
  143. package/src/modules/shared/internal.ts +13 -0
  144. package/src/modules/shared/requirePermission.test.ts +47 -0
  145. package/src/modules/shared/requirePermission.ts +8 -0
  146. package/src/modules/shared/types.ts +4 -0
  147. package/src/modules/supplier-management/.gitkeep +0 -0
  148. package/src/modules/supplier-portal/.gitkeep +0 -0
  149. package/src/modules/testing/index.ts +120 -0
  150. package/src/modules/user-management/README.md +38 -0
  151. package/src/modules/user-management/command/activateUser.test.ts +112 -0
  152. package/src/modules/user-management/command/activateUser.ts +67 -0
  153. package/src/modules/user-management/command/assignPermissionToRole.test.ts +119 -0
  154. package/src/modules/user-management/command/assignPermissionToRole.ts +87 -0
  155. package/src/modules/user-management/command/assignRoleToUser.test.ts +162 -0
  156. package/src/modules/user-management/command/assignRoleToUser.ts +93 -0
  157. package/src/modules/user-management/command/createPermission.test.ts +143 -0
  158. package/src/modules/user-management/command/createPermission.ts +66 -0
  159. package/src/modules/user-management/command/createRole.test.ts +115 -0
  160. package/src/modules/user-management/command/createRole.ts +52 -0
  161. package/src/modules/user-management/command/createUser.test.ts +198 -0
  162. package/src/modules/user-management/command/createUser.ts +85 -0
  163. package/src/modules/user-management/command/deactivateUser.test.ts +112 -0
  164. package/src/modules/user-management/command/deactivateUser.ts +67 -0
  165. package/src/modules/user-management/command/logAuditEvent.test.ts +179 -0
  166. package/src/modules/user-management/command/logAuditEvent.ts +59 -0
  167. package/src/modules/user-management/command/reactivateUser.test.ts +115 -0
  168. package/src/modules/user-management/command/reactivateUser.ts +67 -0
  169. package/src/modules/user-management/command/revokePermissionFromRole.test.ts +112 -0
  170. package/src/modules/user-management/command/revokePermissionFromRole.ts +81 -0
  171. package/src/modules/user-management/command/revokeRoleFromUser.test.ts +112 -0
  172. package/src/modules/user-management/command/revokeRoleFromUser.ts +81 -0
  173. package/src/modules/user-management/db/auditEvent.ts +47 -0
  174. package/src/modules/user-management/db/permission.ts +31 -0
  175. package/src/modules/user-management/db/role.ts +28 -0
  176. package/src/modules/user-management/db/rolePermission.ts +44 -0
  177. package/src/modules/user-management/db/user.ts +38 -0
  178. package/src/modules/user-management/db/userRole.ts +44 -0
  179. package/src/modules/user-management/docs/commands/ActivateUser.md +36 -0
  180. package/src/modules/user-management/docs/commands/AssignPermissionToRole.md +39 -0
  181. package/src/modules/user-management/docs/commands/AssignRoleToUser.md +43 -0
  182. package/src/modules/user-management/docs/commands/CreatePermission.md +35 -0
  183. package/src/modules/user-management/docs/commands/CreateRole.md +35 -0
  184. package/src/modules/user-management/docs/commands/CreateUser.md +41 -0
  185. package/src/modules/user-management/docs/commands/DeactivateUser.md +38 -0
  186. package/src/modules/user-management/docs/commands/LogAuditEvent.md +37 -0
  187. package/src/modules/user-management/docs/commands/ReactivateUser.md +37 -0
  188. package/src/modules/user-management/docs/commands/RevokePermissionFromRole.md +40 -0
  189. package/src/modules/user-management/docs/commands/RevokeRoleFromUser.md +40 -0
  190. package/src/modules/user-management/docs/features/audit-trail.md +80 -0
  191. package/src/modules/user-management/docs/features/role-based-access-control.md +76 -0
  192. package/src/modules/user-management/docs/features/user-account-management.md +64 -0
  193. package/src/modules/user-management/docs/models/AuditEvent.md +34 -0
  194. package/src/modules/user-management/docs/models/Permission.md +31 -0
  195. package/src/modules/user-management/docs/models/Role.md +31 -0
  196. package/src/modules/user-management/docs/models/RolePermission.md +33 -0
  197. package/src/modules/user-management/docs/models/User.md +47 -0
  198. package/src/modules/user-management/docs/models/UserRole.md +34 -0
  199. package/src/modules/user-management/docs/plans/2026-01-30-flattened-permissions-design.md +52 -0
  200. package/src/modules/user-management/executor/recomputeOnRolePermissionChange.ts +61 -0
  201. package/src/modules/user-management/generated/enums.ts +24 -0
  202. package/src/modules/user-management/generated/kysely-tailordb.ts +112 -0
  203. package/src/modules/user-management/index.ts +32 -0
  204. package/src/modules/user-management/lib/errors.ts +81 -0
  205. package/src/modules/user-management/lib/recomputeUserPermissions.ts +53 -0
  206. package/src/modules/user-management/lib/types.ts +31 -0
  207. package/src/modules/user-management/module.ts +77 -0
  208. package/src/modules/user-management/permissions.ts +15 -0
  209. package/src/modules/user-management/tailor.config.ts +11 -0
  210. package/src/modules/user-management/testing/fixtures.ts +98 -0
  211. package/src/schemas.ts +25 -0
  212. package/src/testing.ts +10 -0
  213. package/src/util.ts +3 -0
@@ -0,0 +1,50 @@
1
+ # ConvertAmount
2
+
3
+ ## Overview
4
+
5
+ ConvertAmount transforms a monetary amount from one currency to another using the applicable exchange rate for a given date. The function looks up the most recent exchange rate on or before the specified date and applies it to calculate the converted amount. The result is rounded according to the target currency's decimal precision.
6
+
7
+ This function supports multi-currency operations including transaction recording, financial reporting, and consolidation.
8
+
9
+ ## Business Rules
10
+
11
+ - Source and target currencies must both be active
12
+ - Exchange rate lookup uses the most recent rate with effectiveDate <= conversionDate
13
+ - Calculation: `result = amount x exchangeRate`
14
+ - Result is rounded to the target currency's `decimalPlaces`
15
+ - Same currency conversion (e.g., USD to USD) returns the original amount with rate of 1.0
16
+ - If no direct rate exists, inverse rate may be calculated: `1 / reverseRate`
17
+ - Amount must be non-negative (zero is allowed)
18
+ - Forward rates are supported: if conversion date is in the future and a forward rate exists, it will be used
19
+
20
+ ## Process Flow
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ A[Receive conversion request] --> B{Same currency?}
25
+ B -->|Yes| C[Return original amount]
26
+ B -->|No| D{Both currencies active?}
27
+ D -->|No| E[Return error: inactive currency]
28
+ D -->|Yes| F[Find rate for date]
29
+ F --> G{Direct rate found?}
30
+ G -->|Yes| H[Use direct rate]
31
+ G -->|No| I{Inverse rate found?}
32
+ I -->|Yes| J[Calculate inverse: 1/rate]
33
+ I -->|No| K[Return error: no rate available]
34
+ J --> H
35
+ H --> L[Calculate: amount x rate]
36
+ L --> M[Round to target decimal places]
37
+ M --> N[Return converted amount]
38
+ ```
39
+
40
+ ## External Dependencies
41
+
42
+ - None
43
+
44
+ ## Error Scenarios
45
+
46
+ - **Inactive currency**: Either source or target currency is inactive - return error identifying the inactive currency
47
+ - **No exchange rate**: No rate found for the currency pair on or before the specified date - return error with date and currency pair
48
+ - **Invalid amount**: Negative amount provided - return validation error
49
+ - **Currency not found**: Specified currency code/ID does not exist - return not found error
50
+ - **Date in future**: Conversion date is in the future and no forward rate exists - return error or use most recent rate based on configuration
@@ -0,0 +1,43 @@
1
+ # ConvertQuantity
2
+
3
+ ## Overview
4
+
5
+ ConvertQuantity transforms a quantity from one unit of measure to another within the same category. The conversion uses the category's reference unit as an intermediary, calculating: `result = quantity x sourceConversionFactor / targetConversionFactor`. The result is rounded according to the target unit's precision setting.
6
+
7
+ This function supports core ERP operations where quantities must be expressed in different units for purchasing, inventory, and sales.
8
+
9
+ ## Business Rules
10
+
11
+ - Source and target units must belong to the same UoMCategory
12
+ - Quantity must be a non-negative number (zero is allowed)
13
+ - Conversion factor calculation: `result = quantity x (sourceUnit.conversionFactor / targetUnit.conversionFactor)`
14
+ - Result is rounded to the target unit's `roundingPrecision` decimal places
15
+ - Converting between the same unit returns the original quantity
16
+ - Both units must be active
17
+
18
+ ## Process Flow
19
+
20
+ ```mermaid
21
+ flowchart TD
22
+ A[Receive conversion request] --> B{Same category?}
23
+ B -->|No| C[Return error: incompatible units]
24
+ B -->|Yes| D{Both units active?}
25
+ D -->|No| E[Return error: inactive unit]
26
+ D -->|Yes| F[Get source unit factor]
27
+ F --> G[Get target unit factor]
28
+ G --> H[Calculate: qty x sourceFactor / targetFactor]
29
+ H --> I[Apply target unit rounding precision]
30
+ I --> J[Return converted quantity]
31
+ ```
32
+
33
+ ## External Dependencies
34
+
35
+ - None
36
+
37
+ ## Error Scenarios
38
+
39
+ - **Incompatible units**: Source and target units belong to different categories - return error with message indicating the mismatch
40
+ - **Inactive unit**: Either source or target unit is inactive - return error identifying the inactive unit
41
+ - **Invalid quantity**: Negative quantity provided - return validation error (or allow based on configuration)
42
+ - **Unit not found**: Specified unit ID does not exist - return not found error
43
+ - **Overflow**: Calculation produces a number exceeding system limits - return overflow error
@@ -0,0 +1,44 @@
1
+ # CreateCategory
2
+
3
+ ## Overview
4
+
5
+ CreateCategory establishes a new unit of measure category that groups related units where conversions are meaningful. Each category must have a designated reference unit that serves as the base for all conversion calculations within that category. The reference unit is created simultaneously with the category and has a conversion factor of 1.0.
6
+
7
+ This command supports initial system setup with standard categories (Unit, Weight, Volume, Length, Time) and business-specific category creation.
8
+
9
+ ## Business Rules
10
+
11
+ - Category name must be unique across all categories (active and inactive)
12
+ - Category name is required and must be non-empty
13
+ - Reference unit must be specified at category creation time
14
+ - Reference unit is created with conversion factor of 1.0
15
+ - New categories are created in Active status by default
16
+ - Category cannot exist without at least one unit (the reference unit)
17
+
18
+ ## Process Flow
19
+
20
+ ```mermaid
21
+ flowchart TD
22
+ A[Receive create category request] --> B{Category name provided?}
23
+ B -->|No| C[Return error: missing name]
24
+ B -->|Yes| D{Category name unique?}
25
+ D -->|No| E[Return error: duplicate name]
26
+ D -->|Yes| F{Reference unit specified?}
27
+ F -->|No| G[Return error: missing reference unit]
28
+ F -->|Yes| H[Create category record]
29
+ H --> I[Create reference unit with factor 1.0]
30
+ I --> J[Link reference unit to category]
31
+ J --> K[Set category status: Active]
32
+ K --> L[Return created category with reference unit]
33
+ ```
34
+
35
+ ## External Dependencies
36
+
37
+ - None
38
+
39
+ ## Error Scenarios
40
+
41
+ - **Missing category name**: Name not provided - return validation error
42
+ - **Duplicate category name**: Category with same name already exists - return conflict error
43
+ - **Missing reference unit**: No reference unit details provided - return validation error indicating reference unit is required
44
+ - **Invalid reference unit**: Reference unit details are incomplete or invalid - return validation error with specific issues
@@ -0,0 +1,47 @@
1
+ # CreateCurrency
2
+
3
+ ## Overview
4
+
5
+ CreateCurrency establishes a new monetary unit in the system with its ISO 4217 code, display symbol, name, and decimal precision. The first currency created automatically becomes the organization's base currency. Subsequent currencies are added as available currencies for multi-currency operations.
6
+
7
+ This command supports initial system setup and market expansion scenarios where new trading currencies are needed.
8
+
9
+ ## Business Rules
10
+
11
+ - ISO 4217 code must be exactly 3 uppercase letters
12
+ - ISO 4217 code must be unique across all currencies (active and inactive)
13
+ - Currency symbol is required and typically 1-3 characters
14
+ - Decimal places must be a non-negative integer (0-4 typical range)
15
+ - First currency created automatically becomes the base currency with `isBaseCurrency: true`
16
+ - Subsequent currencies are created with `isBaseCurrency: false`
17
+ - New currencies are created in Active status by default
18
+
19
+ ## Process Flow
20
+
21
+ ```mermaid
22
+ flowchart TD
23
+ A[Receive create request] --> B{Validate ISO code format}
24
+ B -->|Invalid| C[Return error: invalid ISO code]
25
+ B -->|Valid| D{ISO code unique?}
26
+ D -->|No| E[Return error: duplicate code]
27
+ D -->|Yes| F{Validate decimal places}
28
+ F -->|Invalid| G[Return error: invalid decimal places]
29
+ F -->|Valid| H{Is first currency?}
30
+ H -->|Yes| I[Set as base currency]
31
+ H -->|No| J[Set isBaseCurrency: false]
32
+ I --> K[Create currency record]
33
+ J --> K
34
+ K --> L[Set status: Active]
35
+ L --> M[Return created currency]
36
+ ```
37
+
38
+ ## External Dependencies
39
+
40
+ - None
41
+
42
+ ## Error Scenarios
43
+
44
+ - **Invalid ISO code format**: Code is not exactly 3 uppercase letters - return validation error with format requirements
45
+ - **Duplicate ISO code**: Currency with same code already exists - return conflict error with existing currency reference
46
+ - **Invalid decimal places**: Value is negative or exceeds maximum (typically 4) - return validation error with valid range
47
+ - **Missing required fields**: Symbol or name not provided - return validation error listing missing fields
@@ -0,0 +1,48 @@
1
+ # CreateExchangeRate
2
+
3
+ ## Overview
4
+
5
+ CreateExchangeRate establishes a new conversion ratio between a currency pair with a specific effective date. The rate specifies how many units of the target currency equal one unit of the source currency. Rates are date-based to support historical accuracy - transactions use the rate effective on their transaction date.
6
+
7
+ This command supports daily rate updates, period-end rate recording, and forward rate entry for future-dated transactions.
8
+
9
+ ## Business Rules
10
+
11
+ - Source and target currencies must both exist and be active
12
+ - Source and target currencies must be different (no self-conversion rates)
13
+ - Rate value must be a positive decimal number (greater than zero)
14
+ - Effective date is required and determines when the rate becomes applicable
15
+ - Future effective dates are allowed (forward rates)
16
+ - Multiple rates for the same currency pair with different effective dates are allowed
17
+ - When a rate for the same currency pair and effective date already exists, the new rate supersedes (append-only semantics)
18
+ - Rate lookup uses the most recent rate with effectiveDate <= transaction date
19
+
20
+ ## Process Flow
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ A[Receive create rate request] --> B{Source currency exists and active?}
25
+ B -->|No| C[Return error: invalid source currency]
26
+ B -->|Yes| D{Target currency exists and active?}
27
+ D -->|No| E[Return error: invalid target currency]
28
+ D -->|Yes| F{Source != Target?}
29
+ F -->|No| G[Return error: same currency pair]
30
+ F -->|Yes| H{Rate value > 0?}
31
+ H -->|No| I[Return error: invalid rate value]
32
+ H -->|Yes| J{Effective date provided?}
33
+ J -->|No| K[Return error: missing effective date]
34
+ J -->|Yes| L[Create exchange rate record]
35
+ L --> M[Return created rate]
36
+ ```
37
+
38
+ ## External Dependencies
39
+
40
+ - None
41
+
42
+ ## Error Scenarios
43
+
44
+ - **Invalid source currency**: Source currency does not exist or is inactive - return error identifying the currency
45
+ - **Invalid target currency**: Target currency does not exist or is inactive - return error identifying the currency
46
+ - **Same currency pair**: Source and target currencies are the same - return error indicating self-conversion is not allowed
47
+ - **Invalid rate value**: Rate is zero, negative, or not a valid number - return validation error with acceptable range
48
+ - **Missing effective date**: No effective date provided - return validation error indicating date is required
@@ -0,0 +1,48 @@
1
+ # CreateUnit
2
+
3
+ ## Overview
4
+
5
+ CreateUnit adds a new unit of measure to an existing category with its symbol, display name, and conversion factor relative to the category's reference unit. The conversion factor defines how many reference units equal one of this unit.
6
+
7
+ This command supports adding industry-specific units (like "Pallet" or "Roll"), regional units (metric and imperial), and precision units for specialized tracking.
8
+
9
+ ## Business Rules
10
+
11
+ - Target category must exist and be active
12
+ - Unit symbol must be unique within the category
13
+ - Unit symbol is required and typically 1-5 characters
14
+ - Conversion factor must be a positive decimal number (greater than zero)
15
+ - Rounding precision must be a non-negative integer
16
+ - New units are created as non-reference units (only one reference unit per category)
17
+ - The conversion formula is: `quantity_in_reference = quantity_in_this_unit × conversion_factor`
18
+
19
+ ## Process Flow
20
+
21
+ ```mermaid
22
+ flowchart TD
23
+ A[Receive create unit request] --> B{Category exists and active?}
24
+ B -->|No| C[Return error: invalid category]
25
+ B -->|Yes| D{Symbol provided?}
26
+ D -->|No| E[Return error: missing symbol]
27
+ D -->|Yes| F{Symbol unique in category?}
28
+ F -->|No| G[Return error: duplicate symbol]
29
+ F -->|Yes| H{Conversion factor > 0?}
30
+ H -->|No| I[Return error: invalid conversion factor]
31
+ H -->|Yes| J{Rounding precision valid?}
32
+ J -->|No| K[Return error: invalid rounding precision]
33
+ J -->|Yes| L[Create unit record]
34
+ L --> M[Link unit to category]
35
+ M --> N[Return created unit]
36
+ ```
37
+
38
+ ## External Dependencies
39
+
40
+ - None
41
+
42
+ ## Error Scenarios
43
+
44
+ - **Invalid category**: Category does not exist or is inactive - return error identifying the category
45
+ - **Missing symbol**: Unit symbol not provided - return validation error
46
+ - **Duplicate symbol**: Unit with same symbol already exists in category - return conflict error
47
+ - **Invalid conversion factor**: Factor is zero, negative, or not a valid number - return validation error
48
+ - **Invalid rounding precision**: Precision is negative - return validation error with acceptable range
@@ -0,0 +1,38 @@
1
+ # DeactivateCategory
2
+
3
+ ## Overview
4
+
5
+ DeactivateCategory disables a UoM category from being used in new product assignments while preserving all historical data and existing product associations. This command supports scenarios such as discontinuing a measurement standard or consolidating categories.
6
+
7
+ ## Business Rules
8
+
9
+ - Target category must exist in the system
10
+ - Target category must be in Active status
11
+ - Category with active units cannot be deactivated - all units must be deactivated first
12
+ - Deactivating an already inactive category returns success with no state change
13
+ - Historical transactions and products using this category's units are not affected
14
+ - Deactivation prevents new products from being assigned units in this category
15
+
16
+ ## Process Flow
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ A[Receive deactivate request] --> B{Category exists?}
21
+ B -->|No| C[Return error: not found]
22
+ B -->|Yes| D{Has active units?}
23
+ D -->|Yes| E[Return error: has active units]
24
+ D -->|No| F{Current status?}
25
+ F -->|Inactive| G[Return success: already inactive]
26
+ F -->|Active| H[Update status to Inactive]
27
+ H --> I[Return deactivated category]
28
+ ```
29
+
30
+ ## External Dependencies
31
+
32
+ - None
33
+
34
+ ## Error Scenarios
35
+
36
+ - **Category not found**: Specified category ID does not exist - return not found error
37
+ - **Has active units**: Category still contains active units - return error listing active units that must be deactivated first
38
+ - **Invalid category ID**: Malformed or empty ID provided - return validation error
@@ -0,0 +1,38 @@
1
+ # DeactivateCurrency
2
+
3
+ ## Overview
4
+
5
+ DeactivateCurrency disables a currency from being used in new transactions while preserving all historical data. This command supports scenarios such as market exit or currency obsolescence (e.g., legacy national currencies replaced by EUR). Deactivated currencies remain in the system for reporting and audit purposes.
6
+
7
+ ## Business Rules
8
+
9
+ - Target currency must exist in the system
10
+ - Target currency must be in Active status
11
+ - Base currency cannot be deactivated - must first change base currency to another active currency
12
+ - Deactivating an already inactive currency returns success with no state change
13
+ - Historical transactions using this currency are not affected
14
+ - Deactivation prevents the currency from being used in new transactions, exchange rates, or price lists
15
+
16
+ ## Process Flow
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ A[Receive deactivate request] --> B{Currency exists?}
21
+ B -->|No| C[Return error: not found]
22
+ B -->|Yes| D{Is base currency?}
23
+ D -->|Yes| E[Return error: cannot deactivate base currency]
24
+ D -->|No| F{Current status?}
25
+ F -->|Inactive| G[Return success: already inactive]
26
+ F -->|Active| H[Update status to Inactive]
27
+ H --> I[Return deactivated currency]
28
+ ```
29
+
30
+ ## External Dependencies
31
+
32
+ - None
33
+
34
+ ## Error Scenarios
35
+
36
+ - **Currency not found**: Specified currency ID does not exist - return not found error
37
+ - **Base currency protection**: Attempting to deactivate the base currency - return error indicating base currency must be changed first
38
+ - **Invalid currency ID**: Malformed or empty ID provided - return validation error
@@ -0,0 +1,38 @@
1
+ # DeactivateUnit
2
+
3
+ ## Overview
4
+
5
+ DeactivateUnit disables a unit of measure from being used in new product assignments and quantity conversions while preserving all historical data. This command supports scenarios such as discontinuing a measurement unit or consolidating units within a category.
6
+
7
+ ## Business Rules
8
+
9
+ - Target unit must exist in the system
10
+ - Target unit must be in Active status
11
+ - Reference unit cannot be deactivated - must first change reference unit to another active unit in the category
12
+ - Deactivating an already inactive unit returns success with no state change
13
+ - Historical transactions and products using this unit are not affected
14
+ - Deactivation prevents the unit from being used in new product assignments or conversions
15
+
16
+ ## Process Flow
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ A[Receive deactivate request] --> B{Unit exists?}
21
+ B -->|No| C[Return error: not found]
22
+ B -->|Yes| D{Is reference unit?}
23
+ D -->|Yes| E[Return error: cannot deactivate reference unit]
24
+ D -->|No| F{Current status?}
25
+ F -->|Inactive| G[Return success: already inactive]
26
+ F -->|Active| H[Update status to Inactive]
27
+ H --> I[Return deactivated unit]
28
+ ```
29
+
30
+ ## External Dependencies
31
+
32
+ - None
33
+
34
+ ## Error Scenarios
35
+
36
+ - **Unit not found**: Specified unit ID does not exist - return not found error
37
+ - **Reference unit protection**: Attempting to deactivate the category's reference unit - return error indicating reference unit must be changed first
38
+ - **Invalid unit ID**: Malformed or empty ID provided - return validation error
@@ -0,0 +1,39 @@
1
+ # SetBaseCurrency
2
+
3
+ ## Overview
4
+
5
+ SetBaseCurrency changes the organization's base currency to a different active currency. The base currency serves as the default for financial reporting, consolidation, and serves as the reference point for exchange rate conversions. This command supports scenarios such as corporate restructuring or relocating headquarters to a different country.
6
+
7
+ ## Business Rules
8
+
9
+ - Target currency must exist in the system
10
+ - Target currency must be in Active status
11
+ - Only one currency can be base currency at a time
12
+ - Setting the current base currency as base returns success with no change
13
+ - Previous base currency remains active but loses base currency designation
14
+ - Exchange rates may need to be recalculated or new rates added after changing base currency
15
+
16
+ ## Process Flow
17
+
18
+ ```mermaid
19
+ flowchart TD
20
+ A[Receive set base request] --> B{Currency exists?}
21
+ B -->|No| C[Return error: not found]
22
+ B -->|Yes| D{Currency active?}
23
+ D -->|No| E[Return error: cannot set inactive currency as base]
24
+ D -->|Yes| F{Already base currency?}
25
+ F -->|Yes| G[Return success: no change needed]
26
+ F -->|No| H[Remove base flag from current base]
27
+ H --> I[Set base flag on target currency]
28
+ I --> J[Return updated currency]
29
+ ```
30
+
31
+ ## External Dependencies
32
+
33
+ - None
34
+
35
+ ## Error Scenarios
36
+
37
+ - **Currency not found**: Specified currency ID does not exist - return not found error
38
+ - **Inactive currency**: Target currency is not in Active status - return error indicating currency must be activated first
39
+ - **Invalid currency ID**: Malformed or empty ID provided - return validation error
@@ -0,0 +1,43 @@
1
+ # SetReferenceUnit
2
+
3
+ ## Overview
4
+
5
+ SetReferenceUnit changes the reference unit for a UoM category to a different unit within the same category. When the reference unit changes, all conversion factors in the category are automatically recalculated relative to the new reference. The new reference unit's conversion factor becomes 1.0.
6
+
7
+ This command supports scenarios where business requirements change and a different unit becomes the standard for measurement.
8
+
9
+ ## Business Rules
10
+
11
+ - Target unit must exist and belong to the specified category
12
+ - Target unit must be in the same category as the current reference unit
13
+ - Setting the current reference unit as reference returns success with no change
14
+ - When reference unit changes, the new reference unit's conversion factor becomes 1.0
15
+ - All other units' conversion factors are recalculated: `new_factor = old_factor / new_reference_old_factor`
16
+ - Historical conversion calculations are not affected (they used the factors at time of calculation)
17
+
18
+ ## Process Flow
19
+
20
+ ```mermaid
21
+ flowchart TD
22
+ A[Receive set reference request] --> B{Unit exists?}
23
+ B -->|No| C[Return error: unit not found]
24
+ B -->|Yes| D{Unit in specified category?}
25
+ D -->|No| E[Return error: unit not in category]
26
+ D -->|Yes| F{Already reference unit?}
27
+ F -->|Yes| G[Return success: no change needed]
28
+ F -->|No| H[Get new unit's current factor]
29
+ H --> I[Recalculate all unit factors]
30
+ I --> J[Set new unit factor to 1.0]
31
+ J --> K[Update category reference unit pointer]
32
+ K --> L[Return updated category]
33
+ ```
34
+
35
+ ## External Dependencies
36
+
37
+ - None
38
+
39
+ ## Error Scenarios
40
+
41
+ - **Unit not found**: Specified unit ID does not exist - return not found error
42
+ - **Unit not in category**: Unit belongs to a different category than specified - return error with category mismatch details
43
+ - **Invalid unit ID**: Malformed or empty ID provided - return validation error
@@ -0,0 +1,55 @@
1
+ # Currency Definitions
2
+
3
+ ## Overview
4
+
5
+ Currency Definitions establish the monetary units available for use across the ERP system. Each currency record contains the ISO 4217 code, display symbol, name, and decimal precision. One currency is designated as the base currency for the organization, serving as the default for reporting and consolidation.
6
+
7
+ This feature provides the foundation for all multi-currency operations in sales, purchasing, and accounting.
8
+
9
+ ## Business Purpose
10
+
11
+ Organizations operating internationally need to:
12
+
13
+ - Record transactions in the customer's or vendor's preferred currency
14
+ - Convert amounts to a consistent base currency for financial reporting
15
+ - Display currency symbols and format amounts correctly by locale
16
+ - Handle currencies with different decimal precisions (e.g., JPY has 0 decimals, USD has 2)
17
+
18
+ Currency definitions ensure consistent monetary handling across all business operations.
19
+
20
+ ## Process Flow
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ A[Define Currency] --> B{Is First Currency?}
25
+ B -->|Yes| C[Set as Base Currency]
26
+ B -->|No| D[Add to Available Currencies]
27
+ C --> E[Currency Active]
28
+ D --> E
29
+ E --> F[Available for Transactions]
30
+ F --> G[Products Can Set Prices]
31
+ F --> H[Orders Can Use Currency]
32
+ F --> I[Exchange Rates Can Reference]
33
+ ```
34
+
35
+ ## Scenario Patterns
36
+
37
+ - **Initial Setup**: Administrator defines base currency (e.g., USD) and common trading currencies (EUR, GBP, JPY) during system initialization
38
+ - **Market Expansion**: Business enters new market and adds local currency (e.g., BRL for Brazil expansion)
39
+ - **Currency Deactivation**: Obsolete currency (e.g., legacy national currency replaced by EUR) is deactivated to prevent new transactions while preserving historical data
40
+ - **Precision Configuration**: Cryptocurrency or precious metal tracking requires higher decimal precision than standard currencies
41
+
42
+ ## Test Cases
43
+
44
+ - Creating a currency with valid ISO 4217 code should succeed
45
+ - Currency codes must be unique (no duplicate USD)
46
+ - First currency created should automatically become base currency
47
+ - Changing base currency should be allowed only with proper authorization
48
+ - Deactivating the base currency should be prevented
49
+ - Currency with active transactions should not be deletable (only deactivatable)
50
+ - Decimal places must be non-negative integer (0-4 typical range)
51
+
52
+ ## Reference Links
53
+
54
+ - [ISO 4217 Currency Codes](https://www.iso.org/iso-4217-currency-codes.html)
55
+ - [Unicode CLDR Currency Data](https://cldr.unicode.org/index/downloads)
@@ -0,0 +1,61 @@
1
+ # Exchange Rates
2
+
3
+ ## Overview
4
+
5
+ Exchange Rates maintain the conversion ratios between currency pairs with effective dates. Each rate record specifies the source currency, target currency, rate value, and the date from which it applies. The system uses these rates to convert monetary amounts for transactions, reporting, and consolidation.
6
+
7
+ Rates are date-based to support historical accuracy - a transaction from last month uses last month's rate, not today's rate.
8
+
9
+ ## Business Purpose
10
+
11
+ Multi-currency operations require accurate exchange rate management:
12
+
13
+ - **Transaction Recording**: Convert foreign currency invoices to base currency at booking time
14
+ - **Financial Reporting**: Consolidate subsidiaries using period-end rates
15
+ - **Historical Accuracy**: Audit trail requires rates as of transaction date
16
+ - **Variance Analysis**: Compare budgeted rates vs actual rates for currency exposure
17
+
18
+ Exchange rates ensure monetary consistency while maintaining complete audit traceability.
19
+
20
+ ## Process Flow
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ A[Create Exchange Rate] --> B[Set Currency Pair]
25
+ B --> C[Set Rate Value]
26
+ C --> D[Set Effective Date]
27
+ D --> E{Validate Rate}
28
+ E -->|Invalid| F[Return Error]
29
+ E -->|Valid| G[Save Rate]
30
+ G --> H[Rate Available for Date Range]
31
+
32
+ I[Convert Amount] --> J[Find Rate for Date]
33
+ J --> K{Rate Found?}
34
+ K -->|No| L[Return Error or Use Fallback]
35
+ K -->|Yes| M[Apply Rate × Amount]
36
+ M --> N[Return Converted Amount]
37
+ ```
38
+
39
+ ## Scenario Patterns
40
+
41
+ - **Daily Rate Updates**: Finance team updates rates daily from central bank or market data feed
42
+ - **Period-End Rates**: Month-end closing uses official rates for consolidation
43
+ - **Historical Lookup**: Generating report for Q1 uses Q1 rates, not current rates
44
+ - **Rate Gap Handling**: Transaction on holiday uses most recent prior rate when exact date unavailable
45
+ - **Inverse Calculation**: Rate for USD→EUR automatically provides EUR→USD by inversion
46
+
47
+ ## Test Cases
48
+
49
+ - Creating rate with valid currency pair and positive rate should succeed
50
+ - Rate with zero or negative value should fail validation
51
+ - Rate effective date in far future should be allowed (forward rates)
52
+ - Looking up rate for date should return most recent rate on or before that date
53
+ - Looking up rate with no prior rate should return error or configurable fallback
54
+ - Same currency conversion (USD→USD) should return rate of 1.0
55
+ - Inverse rate calculation should be mathematically correct (1/rate)
56
+ - Updating existing rate for same date should replace previous value
57
+
58
+ ## Reference Links
59
+
60
+ - [European Central Bank Exchange Rates](https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html)
61
+ - [Open Exchange Rates API](https://openexchangerates.org/)
@@ -0,0 +1,66 @@
1
+ # Unit Conversion
2
+
3
+ ## Overview
4
+
5
+ Unit Conversion enables automatic quantity transformation between any two units within the same category. The conversion uses the reference unit as an intermediary, ensuring consistent results regardless of which units are involved. This feature supports the core ERP operations where quantities must be expressed in different units for purchasing, inventory, and sales.
6
+
7
+ Conversions include configurable rounding precision to match business requirements for different unit types.
8
+
9
+ ## Business Purpose
10
+
11
+ Different stakeholders work with different units:
12
+
13
+ - **Purchasing** buys in bulk units (cases, pallets, drums)
14
+ - **Warehouse** tracks in standardized units (pieces, kilograms, liters)
15
+ - **Sales** sells in customer-friendly units (packs, bottles, individual items)
16
+ - **Manufacturing** measures in precise units (grams, milliliters)
17
+
18
+ Unit conversion eliminates manual calculation errors and ensures inventory accuracy when the same product moves through these different contexts.
19
+
20
+ ## Process Flow
21
+
22
+ ```mermaid
23
+ flowchart TD
24
+ A[Conversion Request] --> B{Same Category?}
25
+ B -->|No| C[Return Error: Incompatible Units]
26
+ B -->|Yes| D[Get Source Unit Factor]
27
+ D --> E[Get Target Unit Factor]
28
+ E --> F[Calculate: Qty × Source Factor ÷ Target Factor]
29
+ F --> G[Apply Rounding Precision]
30
+ G --> H[Return Converted Quantity]
31
+
32
+ subgraph Validation
33
+ B
34
+ end
35
+
36
+ subgraph Calculation
37
+ D
38
+ E
39
+ F
40
+ G
41
+ end
42
+ ```
43
+
44
+ ## Scenario Patterns
45
+
46
+ - **Purchase to Inventory**: Vendor ships 10 cases (12 units/case), system records 120 pieces in inventory
47
+ - **Sales Order Fulfillment**: Customer orders 5 kg, warehouse picks 5000 grams from bin tracked in grams
48
+ - **Manufacturing Consumption**: Recipe calls for 500ml, inventory deducts 0.5 liters from stock
49
+ - **Cross-Unit Reporting**: Generate report showing total weight in both kilograms and pounds for different markets
50
+ - **Fractional Handling**: Order for 2.5 dozen converts to 30 pieces for picking
51
+
52
+ ## Test Cases
53
+
54
+ - Converting between units in the same category should return correct result
55
+ - Converting between units in different categories should return an error
56
+ - Converting with the same source and target unit should return the original quantity
57
+ - Converting to/from the reference unit should use factor of 1.0
58
+ - Rounding should respect the target unit's precision setting
59
+ - Zero quantity conversion should return zero
60
+ - Negative quantity conversion should be handled consistently (error or allow based on business rules)
61
+ - Very large quantities should not cause overflow errors
62
+
63
+ ## Reference Links
64
+
65
+ - [NIST Unit Conversion Guide](https://www.nist.gov/pml/owm/metric-si/unit-conversion)
66
+ - [Odoo UoM Conversion Documentation](https://www.odoo.com/documentation/19.0/applications/inventory_and_mrp/inventory/product_management/configure/uom.html)