feat(teams): add operation IDs for integration and coach endpoints#3
Conversation
WalkthroughAdds an optional biological_age field to ScoresData in TSP and YAML schemas. Updates OpenAPI v5 specs: changes default semantics of to_webhook to true across multiple endpoints, and adds a required user_id query parameter to POST /plannedWorkout. teams.yml gains operationIds, schema tweaks (e.g., Coach.reference_id), and Test object reorganization. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant C as Client
participant API as API Gateway
participant P as PlannedWorkout Service
participant W as Webhook Router
participant H as Webhook Endpoint(s)
Note over C,API: New required query parameter: user_id
C->>API: POST /plannedWorkout?user_id={id} (body)
API->>P: Validate & forward (user_id, payload)
rect rgba(227,245,255,0.6)
note right of P: to_webhook default now true if omitted
P->>W: Emit event (to_webhook resolved)
alt to_webhook = true
W-->>H: Deliver webhook payload
H-->>W: 2xx/4xx/5xx
else to_webhook = false
W-->>P: Skip webhook
end
end
W-->>P: Ack/Result
P-->>API: Created/Result
API-->>C: 201/Response
sequenceDiagram
autonumber
participant C as Client
participant API as API Gateway
participant S as Resource Services (activity/daily/sleep/...)
Note over C,API: Many GET endpoints: to_webhook default true if not provided
C->>API: GET /{resource}?to_webhook (optional)
API->>S: Fetch resource, resolve to_webhook default
alt to_webhook = true (by default or explicit)
S-->>API: Data + webhook dispatch initiated
else to_webhook = false
S-->>API: Data only
end
API-->>C: 200/Resource payload
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…hook parameter descriptions
ea78cab to
389f376
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
teams.yml (4)
725-729: Stray duplicate "components:" key breaks the document.A second top-level components key will override the earlier one or fail parsing. MetricStats and subsequent schemas must live under components.schemas.
Apply this diff (then outdent MetricStats to align with other schemas under components.schemas):
- components:
889-893: $ref has siblings; wrap with allOf or remove siblings.In OAS 3.1/JSON Schema, $ref should not have sibling keywords. Keep description and ref by using allOf.
Apply this diff:
- athlete: - type: object - description: "Athlete details" - $ref: '#/components/schemas/Athlete' + athlete: + allOf: + - $ref: '#/components/schemas/Athlete' + description: "Athlete details"
1-1: OpenAPI 3.1 declared but using "nullable": update types or downgrade to 3.0."nullable" is not supported in OAS 3.1; use JSON Schema nullables (type: [string, 'null'] or anyOf with null), or change openapi: 3.0.3. Current combo will fail validators/generators.
Options:
- Migrate: replace each
type: string+nullable: truewithtype: [string, 'null'](similarly for number/integer/array/object).- Or downgrade header to
openapi: 3.0.3(fastest stopgap if 3.1 features aren’t needed).Also applies to: 544-555, 550-551, 561-569, 574-579, 616-639, 660-707, 712-717, 731-744
948-976: Move example definitions into a top-levelcomponents.examplessection
Undercomponents:, add anexamples:block at the same level asschemas:, then relocate theErrorCoachNotFound,ErrorInvalidRequest,ErrorUnauthorizedandErrorForbiddenentries fromcomponents.schemasintocomponents.examples.
🧹 Nitpick comments (6)
v5.yaml (2)
352-356: Stateto_webhook’s default in the schemaWe now document the default as “true if not provided,” but the schema blocks still omit an explicit
default. Adding it makes the contract machine-readable (codegen, SDKs) and keeps the behavior synchronized across languages.Apply this diff to each affected
to_webhookparameter:schema: type: boolean + default: trueAlso applies to: 520-523, 613-616, 923-926, 1037-1040, 1151-1154, 1463-1466, 1661-1664
1549-1555: Align the user_id description with the POST semanticsThe new parameter description still says “retrieve data,” which reads like a GET. Tweaking it to “post planned workout data for” will match the operation’s behavior.
Apply this diff:
- - name: user_id - in: query - description: Terra user ID (UUID format) to retrieve data for + - name: user_id + in: query + description: Terra user ID (UUID format) to post planned workout data forv5-bundled.yaml (1)
354-359: Add explicit schema default forto_webhook.Right now the description says the default is
true, but the schema still lacks a machine-readabledefault. Withoutdefault: true, client SDKs generated from this spec will continue to assume there is no default (or a falsey one). Please adddefault: trueunder the schema here and in the otherto_webhookparameter definitions updated in this PR.- name: to_webhook in: query description: | Boolean flag specifying whether to send the data retrieved to the webhook instead of in the response (default: true if not provided) schema: type: boolean + default: true required: falseteams.yml (3)
127-149: Consider a dedicated CoachCreate schema for POST body.Referencing the full Coach object may expose readOnly fields in docs and complicate validation. Prefer a minimal CoachCreate with only writable fields (e.g., reference_id, region, provider, client_id, client_secret).
402-420: Use AthletePartialUpdate for PATCH body.PATCH should accept partial fields; the spec already defines AthletePartialUpdate. Replace the request schema to avoid confusion.
Apply this diff:
requestBody: required: true content: application/json: schema: - $ref: '#/components/schemas/Athlete' + $ref: '#/components/schemas/AthletePartialUpdate'
100-100: Normalize operationId casing for consistency.Mix of PascalCase (GenerateWidgetSession) and lowerCamelCase (getAthletes...). Consider standardizing (e.g., lowerCamelCase) to improve SDK generation and readability.
Also applies to: 115-115, 127-127, 152-152, 174-174, 200-200, 238-238, 272-272, 310-310, 384-384, 402-402
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
data_models/specs/data_models/common.tsp(1 hunks)schemas/ScoresData.yaml(1 hunks)teams.yml(14 hunks)v5-bundled.yaml(9 hunks)v5.yaml(9 hunks)
🔇 Additional comments (14)
data_models/specs/data_models/common.tsp (1)
89-93: Validate biological age upper boundLine 92 caps
biological_ageat 100.0. Biological age is measured in years, and users with chronological/biological ages above 100 are valid albeit rare. Capping at 100 would force us either to reject their data or misrepresent it. Please verify with the data owners whether the upstream data ever exceeds 100; if there's no hard ceiling, raise the max (e.g. 150) or drop it altogether so the spec remains accurate.schemas/ScoresData.yaml (1)
26-32: Mirror the biological age ceiling fixSame concern as in
common.tsp: Line 31’smaximum: 100will misrepresent valid 100+ biological ages. Make sure the cap matches the true data range.v5-bundled.yaml (1)
1489-1495: Requireduser_idlooks good.Adding an explicit, required
user_idquery parameter makes the write endpoint consistent with the rest of the PlannedWorkout surface and clarifies usage. No concerns from me.teams.yml (11)
115-126: LGTM: Added operationId for listCoaches.
152-171: LGTM: Added operationId for deleteCoach.
174-198: LGTM: Added operationId for getAthletesForCoach.
200-235: LGTM: Added operationId for getActivitiesForCoach.
238-269: LGTM: Added operationId for getActivityMetricsSchemaForCoach.
272-308: LGTM: Added operationId for getTestsForCoach.
310-319: LGTM: Response wrapper for GET /athletes.Switch to AthletesReturned improves consistency with other list responses.
384-401: LGTM: Added operationId for getAthlete.
466-469: LGTM: Coach.reference_id added.Good addition for external correlation. Consider documenting uniqueness or constraints if required by upstream systems.
820-820: LGTM: Default movement -1 aligns with UNKNOWN.
100-113: LGTM: AddedoperationId: getDetailedIntegrations; no duplicate operationIds found in teams.yml.
| examples: | ||
| - "https://api.tryterra.co/probs/not-found" | ||
| title: | ||
| type: string | ||
| examples: | ||
| examples: | ||
| - "Resource Not Found" | ||
| status: | ||
| type: integer | ||
| format: int32 | ||
| examples: | ||
| examples: | ||
| - 404 | ||
| detail: | ||
| type: string | ||
| examples: | ||
| examples: | ||
| - "The coach with the provided ID does not exist." |
There was a problem hiding this comment.
Invalid use of "examples" inside Schema properties; use "example" or components/examples.
In OpenAPI 3.1, Schema Object supports "example" (singular). "examples" here will fail validation in many tools.
Apply this diff:
type:
type: string
format: uri
- examples:
- - "https://api.tryterra.co/probs/not-found"
+ example: "https://api.tryterra.co/probs/not-found"
title:
type: string
- examples:
- - "Resource Not Found"
+ example: "Resource Not Found"
status:
type: integer
format: int32
- examples:
- - 404
+ example: 404
detail:
type: string
- examples:
- - "The coach with the provided ID does not exist."
+ example: "The coach with the provided ID does not exist."Also ensure your predefined examples are placed under components.examples (not within components.schemas). See related comment below.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| examples: | |
| - "https://api.tryterra.co/probs/not-found" | |
| title: | |
| type: string | |
| examples: | |
| examples: | |
| - "Resource Not Found" | |
| status: | |
| type: integer | |
| format: int32 | |
| examples: | |
| examples: | |
| - 404 | |
| detail: | |
| type: string | |
| examples: | |
| examples: | |
| - "The coach with the provided ID does not exist." | |
| type: | |
| type: string | |
| format: uri | |
| example: "https://api.tryterra.co/probs/not-found" | |
| title: | |
| type: string | |
| example: "Resource Not Found" | |
| status: | |
| type: integer | |
| format: int32 | |
| example: 404 | |
| detail: | |
| type: string | |
| example: "The coach with the provided ID does not exist." |
🤖 Prompt for AI Agents
In teams.yml around lines 923-937, the Schema properties incorrectly use the
plural "examples" (OpenAPI 3.1 requires the singular "example") and embed
predefined examples inside schema properties; replace each "examples" with a
single "example" containing the representative value (e.g., example:
"https://api.tryterra.co/probs/not-found", example: "Resource Not Found",
example: 404, example: "The coach with the provided ID does not exist.") and
move any shared/reusable example objects into components.examples (referencing
them from the schema with $ref if needed) so the file validates with OpenAPI
3.1.
|
Looks fine |
…biological age field
Summary by CodeRabbit
New Features
Behavior Changes
Documentation