42 - Action Center
Overview
The Action Center is a centralized order approval system for semi-automated trading. When enabled, orders are queued for manual approval before execution, essential for managed accounts and regulatory compliance (RA - Relationship Advisor mode).
Architecture Diagram

Order Mode Configuration
Setting Order Mode
Mode Toggle API
Both user_id and mode are required. mode must be exactly auto or semi_auto; anything else returns HTTP 400.
Semi-Auto Workflow

Database Schema
pending_orders Table
Indexes
Executor-Supported Queued Types
placeorder
Standard order
place_order_service.place_order
smartorder
Position-aware order
place_smart_order_service.place_smart_order
basketorder
Multiple orders
basket_order_service.place_basket_order
splitorder
Split large orders
split_order_service.split_order
optionsorder
Options contracts
place_options_order_service.place_options_order
optionsmultiorder
Multi-leg options order
options_multiorder_service.place_options_multiorder
placegttorder
GTT order placement
place_gtt_order_service.place_gtt_order
Approval dispatch in services/pending_order_execution_service.py handles these seven API types. Any other api_type is answered with Unknown order type: <api_type> and HTTP 400, and the row's broker status is set to rejected.
placegttorder is handled specially on success: the executor stores the broker's trigger_id as broker_order_id and sets broker_status to open. If the GTT placement succeeds without a trigger ID, the row is marked rejected and the call returns HTTP 502.
calculate_action_center_stats() reports a counter per API type as well: total_placeorder, total_smartorder, total_basketorder, total_splitorder, total_optionsorder, total_optionsmultiorder and total_placegttorder.
Restricted Operations
These operations are never queued. Read-only operations execute immediately; destructive operations apply their own service policy and are blocked in semi-auto mode unless analyzer behavior explicitly permits them. The set is IMMEDIATE_EXECUTION_OPERATIONS in services/order_router_service.py, and should_route_to_pending() compares against it case-insensitively.
closeposition
Blocked by close-position service in semi-auto live mode
closeallpositions
Blocked by close-position service in semi-auto live mode
cancelorder
Blocked by cancel-order service in semi-auto live mode
cancelallorder
Blocked by cancel-all service in semi-auto live mode
modifyorder
Blocked by modify-order service in semi-auto live mode
modifygttorder / cancelgttorder
Blocked because a delayed change may target a stale trigger
gttorderbook
Data retrieval
orderstatus
Status query
orderbook
Data retrieval
tradebook
Data retrieval
positions / openposition
Data retrieval
holdings
Data retrieval
funds
Data retrieval
API Endpoints
All Action Center routes are defined on orders_bp (blueprints/orders.py, url_prefix="/") and require a valid session. Every route except /action-center/count also carries @limiter.limit(API_RATE_LIMIT).
/action-center
GET
Server-rendered page (the React SPA serves the same path)
/action-center/api/data
GET
Orders and statistics as JSON
/action-center/approve/<order_id>
POST
Approve and execute one order
/action-center/reject/<order_id>
POST
Reject one order
/action-center/delete/<order_id>
DELETE
Delete one non-pending order
/action-center/approve-all
POST
Approve and execute every pending order
/action-center/count
GET
Pending count for the nav badge
Get Orders
status accepts pending, approved, rejected or all, and defaults to pending. Statistics are always calculated over all of the user's orders, not just the filtered subset.
Response:
raw_order_data is the stored payload with apikey and api_key stripped out.
Approve Order
Response:
If the order is approved but broker execution fails, the response is {"status": "warning", "message": "Order approved but execution failed", "error": "..."} returned with the service's own status code.
Reject Order
Approve All
Response:
status is success when every approved order executed, warning when some executed, and error when none did. With nothing pending, the response is {"status": "info", "message": "No pending orders to approve"}.
Delete Order
Note: Only approved or rejected orders can be deleted.
Get Pending Count
Response:
Real-Time Updates
SocketIO Events
pending_order_created
New order queued by order_router_service.queue_order()
pending_order_id, user_id, api_type, message
pending_order_updated
Approve, reject, delete or approve-all
action (approved, rejected, deleted or batch_approved), order_id, user_id. The batch variant sends count instead of order_id
pending_order_created is emitted through socketio.start_background_task() and is best-effort: if the emit fails, the queued row still stands and the caller still receives a success response.
Frontend Handling
React Component Features
Tabbed Interface
Statistics Dashboard
Order Table Columns
Strategy
Strategy name
Symbol
Trading symbol
Exchange
NSE/NFO/MCX badge
Action
BUY (green) / SELL (red)
Quantity
Order quantity
Price
Price or "MARKET"
Order Type
placeorder/smartorder/etc
Product
CNC/MIS/NRML badge
Created
Relative time ("5 min ago")
Actions
Approve/Reject/Delete buttons
Expandable Details
Click chevron to view raw order data:
Service Implementation
Order Router
Any exception inside should_route_to_pending() is caught and returns False, so an unexpected failure falls back to immediate execution rather than silently queueing.
Queue Order
Execute Approved Order
Passing auth_token and broker into the service is what stops the approved order from being routed back into the pending queue a second time. If any of api_key, auth_token or broker is missing, the row is marked rejected and the call returns HTTP 403.
Batch responses (basket and split orders) are flattened by _flatten_execution_results() and the resulting broker order IDs are joined into the 255 character broker_order_id column, truncated to <first_id> (+N more) when they do not fit.
Security & Compliance
Audit Trail
All actions are logged with:
Timestamp (IST)
Username
Action taken
Reason (for rejections)
API Key Security
API keys never stored in pending_orders
Only user_id reference maintained
Keys retrieved at execution time
Analyzer Mode Restriction
When in semi_auto mode, the API-key path of the analyzer toggle (services/analyzer_service.py) is blocked with HTTP 403 to ensure SEBI Research Analyst compliance: mode switching stays a client-only decision made through the UI. Internal calls that already carry auth_token and broker are not affected.
Key Files Reference
database/action_center_db.py
PendingOrder model
services/action_center_service.py
Order parsing, stats
services/order_router_service.py
Route decisions
services/pending_order_execution_service.py
Execute approved
blueprints/orders.py
Action center routes
blueprints/apikey.py
Mode toggle
frontend/src/pages/ActionCenter.tsx
React UI
Last updated
Was this helpful?