This service is the NestJS and TypeScript replacement for the event, topic, and health portions of the legacy tc-bus-api. Bus URLs use the /v6/bus prefix.
The following sibling services publish through the Bus API. The timing shown here is based on active production call sites; tests, mocks, generated files, and worktrees are excluded.
| Service | When it publishes events |
|---|---|
autopilot-v6 |
After the scheduler successfully opens or closes a challenge phase, to email reviewers who opted in to phase-change notifications. |
challenge-api-v6 |
After challenge create, update, or delete operations and after create, update, or delete operations for phases, attachments, challenge types and tracks, timeline templates, challenge timeline mappings, and default reviewers. It also publishes configured notification and email events. |
engagements-api-v6 |
When members are assigned to private engagements, applications move to under-review or rejected, assignment offers are created or changed, and members accept or reject offers. Assignment and application notifications are sent as email events. |
forums-api-v6 |
After a topic or post is created in a watched forum, when there are eligible watchers to notify by email. |
groups-api-v6 |
After group create, bulk create, update, or delete operations; subgroup create or delete operations; membership additions or removals; and group-member role additions or removals. |
identity-api-v6 |
During user registration, activation, deactivation, handle changes, and primary-email changes, and when sending password-reset, activation, activation-resend, welcome, and two-factor authentication emails. |
learning-paths-api |
When users enroll in, start, or complete certification and FCC learning flows; when TCA completion is recorded; and when the administrative utility explicitly submits an event. |
leave-api-v6 |
On the last UTC day of each month, to send the monthly leave reminder email to Topcoder Staff members. |
marathon-match-api-v6 |
After provisional/example submission scoring or final system scoring completes, to send the scoring-completion email once per submission and scoring stage. |
member-api-v6 |
After member profile updates, including email changes, and after member-trait create, update, or delete operations. |
projects-api-v6 |
After project create, update, billing-account update, or delete operations; member additions or removals; and invite create, update, accept, or remove operations. It also publishes project-invite and copilot workflow emails. Retained metadata publisher call sites are currently no-ops. |
resource-api-v6 |
After challenge-resource create or delete operations and resource-role create or update operations, when resource creation requires an email notification, and when handled resource operations report an error event. |
review-api-v6 |
When submissions are created or sent for antivirus scanning; when scanned First2Finish, Topgear, or Marathon Match submissions are released for processing; when reviews, appeal responses, or AI workflows complete; when approved review applications create resources; and when review, contact, escalation, or workflow emails are required. |
submission-scanner-processor |
After an antivirus scan completes or fails closed, when the request selected a Kafka callback; the result is published to the request's whitelisted callback topic. |
tc-finance-api |
When an OTP email is requested and when a winnings transaction needs to remind a member to finish payment or tax setup. |
tc-project-service |
Across the legacy project lifecycle: project, member, invite, attachment, phase, milestone, timeline, phase-product, and customer-payment changes, plus Connect notifications and copilot/member-invite emails. |
terms-receiver |
While processing DocuSign callbacks, including support-email requests, tax-form updates, envelope status updates, and user agreement events. |
terms-service |
After terms-of-use and resource-terms create, update, or delete operations, when a user agrees to terms, and when a DocuSign envelope is created. |
timeline-wall-api |
When an administrator approves or rejects a submitted timeline event, to email its creator. |
Other platform callers in this repository also need to move to the v6 path:
auth0-configpublishesmember.action.loginfrom the login-notifier Auth0 action after an interactive login to the Topcoder application.platform-uipublishes events when an administrator starts a Marathon Match test, requests an antivirus rescan, or reprocesses a First2Finish or Topgear submission.
tc-mm-processor contains an exported helper that can publish common.error.reporting, but there is no active in-repository call site for that helper.
Current callers use a mix of tc-bus-api-wrapper with a BUSAPI_URL base, complete endpoint variables such as BUS_API_URL or BUSAPI_EVENTS_URL, and code that constructs or hard-codes /v5/bus/events. During migration, verify the resolved write URL for each caller is exactly POST /v6/bus/events; whether the configured value is a base URL or a complete endpoint differs by service.
The API publishes complete legacy-compatible event bodies, lists Kafka topics, and reports Kafka-backed service health. Protected endpoints accept Topcoder M2M Bearer tokens validated with AUTH_SECRET and VALID_ISSUERS.
nvm use
pnpm install
cp .env.sample .env
pnpm start:devThe service loads .env during startup before application configuration is
evaluated. Variables already exported by the shell take precedence over values
in the file.
After starting the service on the default port, the Swagger UI is available at http://localhost:3000/v6/bus/api-docs.
POST /v6/bus/eventsrequires thewrite:bus_apiM2M scope and returns202 Acceptedwithout a body after Kafka accepts the event.GET /v6/bus/topicsrequires theread:bus_topicsM2M scope and returns the Kafka topic names.HEAD /v6/bus/topicsrequires the same scope and runs the same metadata availability path without a body.GET /v6/bus/healthandHEAD /v6/bus/healthare unauthenticated. They succeed only while Kafka is both ready and connected; GET returns exactly{ "health": "ok" }and HEAD returns no body.
Event bodies must be JSON objects with own properties named topic, originator, timestamp, mime-type, and payload. Topics must match ^([a-zA-Z0-9]+\.)+[a-zA-Z0-9]+$; the string fields follow the legacy contract, and optional key must be a string. Additional fields are preserved and the submitted object is published without sanitizing, renaming, or stripping properties.
| Variable | Default/sample | Purpose |
|---|---|---|
PORT |
3000 |
HTTP listen port. |
NODE_ENV |
development |
Runtime environment name. |
AUTH_SECRET |
empty | Shared secret used by Topcoder JWT validation. |
VALID_ISSUERS |
Topcoder development and production issuer JSON array | Accepted JWT issuers. |
KAFKA_BROKERS |
localhost:9092 |
Comma-separated Kafka broker list. |
KAFKA_CLIENT_ID |
bus-api-v6 |
Kafka client identifier. |
KAFKA_TLS_ENABLED |
false |
Enables Kafka TLS. |
KAFKA_TLS_REJECT_UNAUTHORIZED |
true |
Enables Kafka TLS certificate verification. |
KAFKA_SASL_MECHANISM |
empty | Kafka SASL mechanism. |
KAFKA_SASL_USERNAME |
empty | Kafka SASL username. |
KAFKA_SASL_PASSWORD |
empty | Kafka SASL password. |
KAFKA_CONNECTION_TIMEOUT |
10000 |
Kafka connection timeout in milliseconds. |
KAFKA_REQUEST_TIMEOUT |
30000 |
Kafka request timeout in milliseconds. |
KAFKA_RETRY_ATTEMPTS |
5 |
Kafka retry attempt count. |
KAFKA_INITIAL_RETRY_TIME |
100 |
Initial Kafka retry delay in milliseconds. |
KAFKA_MAX_RETRY_TIME |
30000 |
Maximum Kafka retry delay in milliseconds. |
LOG_LEVEL |
info |
Application logging level. |
CORS_ALLOWED_ORIGIN |
empty | Optional additional exact CORS origin. |
The shared producer-focused integration uses @platformatic/kafka with the v6-only KAFKA_* environment variables listed above. It owns one producer and one admin metadata client, exposes the readiness and connection status used by health handling, and closes both clients through Nest shutdown hooks.
Publishing serializes the complete submitted event body as JSON rather than publishing only its payload. The optional event key is included only when supplied. Each message contains exactly the buffer-backed originator, mime-type, timestamp, and topic Kafka headers, preserving the mime-type spelling.
Topic listing always attempts a fresh all-topic metadata query. Successful results replace an in-memory last-known topic snapshot and refresh timestamp; when a later query fails, the snapshot is returned defensively. Metadata failures before any successful snapshot produce a server error from the topics endpoints.
nvm use
pnpm lint
pnpm build