Commit 198eb66
* docs: add ADR 001 documenting user confirmation pattern
Add Architecture Decision Record documenting the choice to use
FastMCP Elicitation for user confirmation on destructive operations.
Documents:
- Context and problem statement
- 4 options considered (pre-flight, parameter, prompt, elicitation)
- Decision rationale (MCP-native, industry best practice)
- Implementation pattern with code examples
- Tool categorization by risk level
- Testing requirements
- Consequences and validation criteria
Decision: Use FastMCP Elicitation (MCP native protocol)
Rationale: Standard protocol, strong safety guarantees, rich context,
excellent developer experience
* test: update purchase order and sales order deletion tests for elicitation
- Replace old deletion tests with elicitation pattern tests
- Add imports for AcceptedElicitation, DeclinedElicitation, CancelledElicitation
- Test all elicitation response paths (not found, accepted, declined, cancelled)
- Align with product and supplier test patterns
- All 276 tests passing
* test: implement autospec for service mocks to enforce interface compliance
Use create_autospec() for all service mocks in conftest.py to prevent
tests from passing while mocking non-existent methods. This ensures
that test mocks always match the actual service interfaces.
Benefits:
- Tests will fail immediately if they mock non-existent methods
- Prevents bugs where tests pass but production code fails
- Provides better refactoring safety
- Catches method name typos and signature mismatches
This change was implemented after discovering that tests were mocking
services.suppliers.list_suppliers() instead of list_all(), which
allowed the bug to slip through to the resource implementation.
All 276 tests pass with autospec enforcement.
Addresses: #82
* fix: add nullable enum support to client regeneration + fix resource bug
1. Add nullable enum field support to regeneration script
- Add `add_nullable_to_enum_fields()` function
- Mark OrderPlanFilterCriteria.currentStatus as nullable
- Fixes "None is not a valid CurrentStatusEnum" errors
- Addresses: #83
2. Fix supplier directory resource method name
- Change `list_suppliers()` to `list_all()`
- This bug was caught by autospec implementation
- Related: #82
The regeneration script now handles enum fields that can be null in
API responses, using the allOf + nullable pattern for OpenAPI 3.0.
* fix: regenerate client with nullable currentStatus enum field
Regenerated Python client from StockTrim OpenAPI spec with the
nullable enum field fix applied. The currentStatus field in
OrderPlanFilterCriteria can now handle null values from the API.
Changes:
- OrderPlanFilterCriteria.currentStatus is now CurrentStatusEnum | None | Unset
- from_dict() properly handles None values without throwing validation errors
This fixes the "None is not a valid CurrentStatusEnum" error when
querying order plan data.
Fixes: #83
* fix: remove limit parameter from ProductService.list_all() calls
The ProductService.list_all() method doesn't accept a limit parameter,
but foundation.py was calling it with limit=50. This was caught when
testing resources with MCP Inspector at runtime.
Root cause: test_foundation.py was using mock_foundation_context which
overrode the autospec'd services from conftest.py with plain AsyncMock,
so tests couldn't catch the interface mismatch.
Changes:
- foundation.py: Remove limit=50 from list_all() call, use slicing instead
- test_foundation.py: Remove mock_foundation_context fixture that was
overriding autospec'd services with plain AsyncMock
- test_foundation.py: Update all tests to use mock_context directly
- test_foundation.py: Fix catalog limit test to verify slicing behavior
This ensures autospec catches interface mismatches in resource tests.
* fix: use bulk endpoint for listing all suppliers
The Suppliers.get_all() method was incorrectly using /api/Suppliers
endpoint without a code parameter, which returns 404. The StockTrim API
has separate endpoints for different supplier operations:
- /api/Suppliers?code=X - returns single supplier (requires code)
- /api/SuppliersBulk - returns all suppliers (no parameters)
This is different from other endpoints like Customers and Products which
return arrays from their main endpoint.
Changes:
- Import get_api_suppliers_bulk from generated API
- Use bulk endpoint when code is UNSET (listing all)
- Use single endpoint when code is provided (get specific supplier)
- Update docstring to clarify the conditional behavior
This fixes the 404 error in the supplier directory MCP resource.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f1209d8 commit 198eb66
21 files changed
Lines changed: 1572 additions & 237 deletions
File tree
- docs
- architecture/decisions
- mcp-server
- scripts
- stocktrim_mcp_server
- src/stocktrim_mcp_server
- resources
- tools/foundation
- tests
- test_resources
- test_tools/test_foundation
- stocktrim_public_api_client
- generated/models
- helpers
Lines changed: 287 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
0 commit comments