Design an order-management service that processes incoming messages (NEW, IN_PROGRESS, FILLED, CANCEL) while guaranteeing idempotency. Each message carries an orderId, an idempotencyKey, a messageType, and optional fields such as quantity or price. The service must:
Ignore any message whose idempotencyKey has already been seen (duplicate detection).
Maintain a simple state machine per order: NEW → IN_PROGRESS → COMPLETED, with CANCELLED as an explicit terminal state. Only valid transitions are allowed; invalid ones are silently ignored.
Accumulate filled quantity as multiple FILLED messages arrive; when total filled quantity ≥ original order quantity, move the order to COMPLETED.
Handle edge cases: FILLED or CANCEL for a non-existent or already-terminal order must be ignored; quantity in FILLED may exceed the remaining quantity, in which case the order still transitions to COMPLETED.
Expose two query methods:
getOrderState(orderId) → current state (or NEW if never seen)
getProcessedKeys() → collection of all idempotency keys that have been successfully processed
The implementation must be thread-safe and support high concurrency. You may assume messages are delivered at least once, but not necessarily exactly once.