.cursor/skills/drogon-cpp-engineer/SKILL.md
Develops, debugs, and scales high-performance Drogon C++ web apps—PostgreSQL via DbClient/ORM, RabbitMQ (AMQP-CPP) with Trantor event-loop integration, HttpController and WebSocketController, drogon_ctl scaffolding, config.json, HttpFilter middleware. Use when editing Drogon code, Postgres, messaging, drogon::app(), CMake, or C++ web APIs in this repository.
npx skillsauth add Pk13055/tws-drogon-docker-template drogon-cpp-engineerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Expertise for high-performance Drogon services: non-blocking I/O, PostgreSQL through Drogon’s async stack, RabbitMQ messaging, ORM usage, and safe scaling. Apply when working on the tws service or other Drogon-based C++ in this repo. Prefer patterns already used here; match existing namespaces and file layout.
drogon::HttpController or drogon::WebSocketController classes.drogon_ctl for scaffolding (controllers, models, views).config.json: db_clients, logging, SSL/TLS, or static file settings.DbClient.find_package(Drogon CONFIG REQUIRED), link Drogon::Drogon, C++17 (tws/CMakeLists.txt).drogonframework/drogon:latest (tws/Dockerfile); app listens on 0.0.0.0:8080 unless changed.drogon::HttpController<Derived>, METHOD_LIST_BEGIN / METHOD_ADD / METHOD_LIST_END, route paths and HTTP methods in the macro (tws/controllers/).tws/messaging/, RabbitMQ broker)—follow existing loop integration there.drogon::HttpController<YourController> (CRTP). Declare handlers as member functions.METHOD_ADD(Class::handler, "/path/.../{param}", drogon::Get|Post|...); include drogon::Options when CORS preflight is needed. If the project also defines routes in config.json, keep controller macros and config in sync when both apply.const drogon::HttpRequestPtr &, std::function<void(const drogon::HttpResponsePtr &)> &&callback, and path parameters as trailing arguments if routed with {1} etc.drogon::HttpResponse::newHttpJsonResponse(Json::Value) or other newHttp* factories; always return a HttpResponsePtr by invoking callback(response) on every path (including errors).drogon::DbClient for all database I/O so work stays on Drogon’s asynchronous, non-blocking engine (never raw blocking PG calls in handlers).execSqlCoro for readable async SQL when the toolchain supports it (coroutines require a sufficient C++ standard and Drogon build—this repo is C++17, so use execSqlAsync / callback-based APIs here unless the project is upgraded). When coroutines are available, prefer execSqlCoro over callback-heavy execSqlAsync in new code.drogon_ctl create model <path> against your Postgres schema to generate C++ model classes; then use Mapper<ModelName>(dbClient) for type-safe access.dbClient->newTransaction() (or equivalent API for your Drogon version) so changes stay ACID.DbClient via std::shared_ptr and use Drogon’s connection pools—do not open ad-hoc connections per request (see Critical constraints).trantor::EventLoop (e.g. drogon::app().getIOLoop(index)) so I/O does not block HTTP threads—mirror tws/messaging/ patterns.HttpController handlers (stalls the whole event loop). If used at all, isolate on a worker thread and post results back to Drogon.registerBeginningAdvice—so handlers use a long-lived client, not per-request connects.trantor::EventLoop tied to Drogon (getIOLoop), or a dedicated thread that posts back to Drogon for HTTP-visible state—avoid competing with request handling on the same tight blocking path.drogon::WebSocketController<Derived> and register WebSocket routes per Drogon docs; same non-blocking discipline as HTTP handlers.drogon::HttpFilter subclasses for cross-cutting concerns (headers, auth, logging). Register filters on routes or globally as the project pattern dictates..csp templates are compiled into C++—edit source .csp files. Do not hand-edit generated .h / .cc under filters or views build outputs; regenerate via the build / drogon_ctl instead.drogon::app().registerHandler(path, lambda, {methods}) for ad-hoc routes without a controller class.registerBeginningAdvice, registerPostHandlingAdvice, etc. for startup/shutdown ordering; use for wiring subsystems that must start after the framework is ready.drogon::app().getThreadNum() and Trantor I/O loops when bridging non-Drogon async libraries: schedule work with drogon::app().getIOLoop(index) where the codebase already does so (see messaging integration).env.example / compose for ports and external services.config.json — Postgres: Under db_clients, define name, host, port, database_name, and pool settings as needed for your Drogon version; align names with code that calls app().getDbClient("name").PG_PASSWORD, RABBITMQ_URL, and similar in environment variables (or secrets injection), not committed plaintext in config.json.config.json when used; this project may still set some options in code (addListener, setThreadNum).# Scaffold
drogon_ctl create controller <Name>
drogon_ctl create model <path/to/model>
# Typical local build
mkdir -p build && cd build && cmake .. && cmake --build .
# Run (replace with binary name, e.g. tws)
./<project_name>
HttpController with METHOD_ADD and correct path/method (and config.json if the project routes there too).request APIs; validate inputs before side effects.callback; handle errors with proper HTTP codes.main.cc.DbClient pool + async APIs / Mapper; never open new DB connections per request.trantor::EventLoop as in existing messaging code.DbClient pools and long-lived messaging clients initialized at startup.HttpController code paths—they block the event loop and stall all requests.callback on a branch still hangs the client; same discipline for async DB/messaging completions before responding.callback on some branches (hangs the client)..csp or regenerating.tools
Builds and debugs Interactive Brokers TWS API integration in C++ (twsapi)—connectivity, EReader/EClientSocket, contract builders (STK/OPT/FUT/BAG), market data and snapshot pricing, order CRUD and combo orders, EWrapper execution hooks, Docker/SDK/CMake, env IBKR_HOST/IBKR_PORT/IBKR_CLIENT_ID, tws/ibkr/ and controllers. Use when implementing or changing IBKR trading, pricing, contracts, or gateway wiring in the tws service.
tools
Use when work should span one or more detached tasks but still behave like one job with a single owner context. TaskFlow is the durable flow substrate under authoring layers like Lobster, ACPX, plugins, or plain code. Keep conditional logic in the caller; use TaskFlow for flow identity, child-task linkage, waiting state, revision-checked mutations, and user-facing emergence.
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------
tools
# Lobster Lobster executes multi-step workflows with approval checkpoints. Use it when: - User wants a repeatable automation (triage, monitor, sync) - Actions need human approval before executing (send, post, delete) - Multiple tool calls should run as one deterministic operation ## When to use Lobster | User intent | Use Lobster? | | ------------------------------------------------------ | --------------------------