Skip to content

Define report schema in more detail#29

Merged
phev8 merged 8 commits intocase-framework:mainfrom
kschneider84:api-docs
Dec 22, 2025
Merged

Define report schema in more detail#29
phev8 merged 8 commits intocase-framework:mainfrom
kschneider84:api-docs

Conversation

@kschneider84
Copy link
Copy Markdown
Contributor

@kschneider84 kschneider84 commented Dec 18, 2025

For the endpoint: /v1/study-service/participant-data/{studyKey}/reports
Define the response schemas in more detail.

Summary by CodeRabbit

  • API Changes

    • PaginationInfos tightened: explicit paging fields added and unknown properties disallowed.
    • Report schema clarified across APIs: explicit fields added (id described as MongoDB hex string, added modifiedAt), required fields set (key, participantID, timestamp), and unknown properties disallowed.
    • Report.data items standardized to a named item schema; dtype now constrained to: date, float, int, string, rawMessage, keyList.
  • Documentation

    • Docs updated to include modifiedAt on Report.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 18, 2025

Walkthrough

Tightens public OpenAPI schemas: replaces permissive object shapes with explicit properties, required fields, and closed objects (additionalProperties: false) for PaginationInfos and Report; refines Report.data items and constrains dtype to a specific enum. (≤50 words)

Changes

Cohort / File(s) Summary
Participant API OpenAPI schema
public/openapi/participant-api.json
Replaced permissive schemas with explicit definitions: PaginationInfos now declares integer properties totalCount, currentPage, totalPages, pageSize and disallows extra properties. Report now lists id, key, participantID, responseID, timestamp, modifiedAt, data; marks key, participantID, timestamp required; disallows extra properties; and defines data items with key, value, and a dtype enum ("date", "float", "int", "string", "rawMessage", "keyList").
Management API OpenAPI schema
public/openapi/management-api.json
Aligned Report schema: id description updated to "MongoDB ObjectID as hex string"; timestamp described as Unix timestamp; key, participantID, timestamp marked required; data changed to reference #/components/schemas/ReportData. ReportData introduced as a closed object with key (string), value (string), and dtype (enum with the same values as above).
Documentation
content/docs/participant-management/reports.mdx
Documentation updated to include a new modifiedAt field (string, date-time) on the Report type; docs reflect the expanded Report schema.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Areas to inspect closely:
    • Impact of newly required Report fields (key, participantID, timestamp) on clients and integrations.
    • Consistency of dtype enum values and spelling across both OpenAPI files.
    • modifiedAt type/format consistency between schema and documentation.
    • id and timestamp descriptions (MongoDB hex string vs. Unix timestamp) for clarity.

Possibly related PRs

  • add doc page for reports #15 — Edits the same documentation page content/docs/participant-management/reports.mdx; likely related to adding or modifying the modifiedAt field.

Poem

🐇
I nibble fields and tidy the trail,
enums snug, no loose detail,
timestamps counted, IDs refined,
reports now neat — hop, all aligned. 🥕✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Define report schema in more detail' directly and accurately reflects the main objective of the changeset, which is to add explicit property definitions and constraints to the Report and related schemas across multiple API documentation files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c9057bf and 4fb9077.

📒 Files selected for processing (1)
  • public/openapi/participant-api.json (2 hunks)
🧰 Additional context used
🪛 Biome (2.1.2)
public/openapi/participant-api.json

[error] 3656-3656: Expected a property but instead found '}'.

Expected a property here.

(parse)

🔇 Additional comments (2)
public/openapi/participant-api.json (2)

3619-3637: LGTM! Well-defined pagination schema.

The explicit property definitions with additionalProperties: false improve type safety and API contract clarity.


3643-3689: Good schema definition; approve after fixing the syntax issues.

The explicit Report schema with detailed properties, required fields, and additionalProperties: false significantly improves type safety and API contract clarity. The nested data structure is well-defined with appropriate constraints.

Comment thread public/openapi/participant-api.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
public/openapi/management-api.json (1)

833-839: Tightened Report schema looks good; consider wiring data items to ReportData for consistency

Making key, participantID, responseID, and timestamp required plus adding the description is a solid improvement and aligns with how reports are used elsewhere in this spec. One optional follow-up you might consider (either here or in a later PR) is to reuse the existing ReportData schema for Report.data.items so that the list endpoint and the update endpoint share the same, fully-typed item shape.

For example:

Optional: reuse ReportData in Report.data
       "data": {
         "type": "array",
-        "items": {
-          "type": "object",
-          "additionalProperties": true
-        }
+        "items": {
+          "$ref": "#/components/schemas/ReportData"
+        }
       }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4fb9077 and e2a7195.

📒 Files selected for processing (1)
  • public/openapi/management-api.json (1 hunks)

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
public/openapi/management-api.json (1)

804-830: Clarify timestamp unit for Report.timestamp

The timestamp field now has type: integer with description "Unix timestamp", but other places (e.g., expiresAt) explicitly say "Unix timestamp (seconds)". To avoid ambiguity for clients and tooling, consider specifying whether this is seconds or milliseconds.

Example tweak
-          "timestamp": {
-            "type": "integer",
-            "description": "Unix timestamp"
-          },
+          "timestamp": {
+            "type": "integer",
+            "description": "Unix timestamp (seconds)"
+          },
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2a7195 and 2db9aea.

📒 Files selected for processing (1)
  • public/openapi/management-api.json (3 hunks)
🔇 Additional comments (1)
public/openapi/management-api.json (1)

833-839: Report required fields look consistent

Marking key, participantID, responseID, and timestamp as required matches the defined properties and will help consumers rely on these fields always being present. No issues from a schema perspective.

Comment thread public/openapi/management-api.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
public/openapi/management-api.json (1)

804-851: Clarify Report.required fields vs documented optional responseID

The Report/ReportData schemas look good (closed object, shared ReportData ref, constrained dtype enum). However, there's a mismatch between the schema and documentation: in the OpenAPI schema, responseID is listed as required, but the documentation describes it as "Identifier of the originating response or event, if any" and does not mark it as required in the TypeTable.

If responseID is genuinely optional (not always present for all reports), remove it from the required array:

"required": [
  "key",
  "participantID",
  "timestamp"
]

Alternatively, update the documentation to mark responseID as required and clarify that it is always present.

🧹 Nitpick comments (3)
public/openapi/participant-api.json (3)

3622-3636: Consider marking pagination properties as required.

All four pagination properties (totalCount, currentPage, totalPages, pageSize) appear essential for pagination functionality. Without a required array, the schema permits responses with incomplete pagination info.

🔎 Proposed refinement
 "PaginationInfos": {
     "type": "object",
     "description": "Pagination information",
     "properties": {
-    "totalCount": {
-        "type": "integer"
-    },
-    "currentPage": {
-        "type": "integer"
-    },
-    "totalPages": {
-        "type": "integer"
-    },
-    "pageSize": {
-        "type": "integer"
-    }
+        "totalCount": {
+            "type": "integer"
+        },
+        "currentPage": {
+            "type": "integer"
+        },
+        "totalPages": {
+            "type": "integer"
+        },
+        "pageSize": {
+            "type": "integer"
+        }
     },
+    "required": [
+        "totalCount",
+        "currentPage",
+        "totalPages",
+        "pageSize"
+    ],
     "additionalProperties": false
 }

3647-3650: Consider adding id to required fields.

The id field represents the MongoDB ObjectID and is typically always present. Adding it to the required array ensures API clients can rely on its presence.

🔎 Proposed refinement
 "required": [
+    "id",
     "key",
     "participantID",
     "responseID",
     "timestamp"
 ],

3670-3680: Tighten data item schema with required fields and additionalProperties constraint.

The data items lack a required array and additionalProperties constraint. Given that the PR tightens schemas with explicit properties and additionalProperties: false for both PaginationInfos and Report, the data items appear inconsistent.

🔎 Proposed refinement
 "data": {
     "type": "array",
     "items": {
         "type": "object",
         "properties": {
             "key": { "type": "string" },
             "value": { "type": "string" },
             "dtype": { 
                 "type": "string", 
                 "enum": ["date", "float", "int", "string", "rawMessage", "keyList"]
             }
-        }
+        },
+        "required": ["key", "value", "dtype"],
+        "additionalProperties": false
     }
 }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2db9aea and caa4359.

📒 Files selected for processing (3)
  • content/docs/participant-management/reports.mdx (1 hunks)
  • public/openapi/management-api.json (3 hunks)
  • public/openapi/participant-api.json (2 hunks)
🔇 Additional comments (2)
content/docs/participant-management/reports.mdx (1)

41-44: modifiedAt docs align with the API schema

The new modifiedAt field is documented as an optional string date-time of the last modification, which matches the OpenAPI Report.modifiedAt (string, date-time, not required). Looks consistent and clear.

public/openapi/participant-api.json (1)

3654-3656: Past issues resolved.

The trailing comma syntax error previously flagged at line 3656 and the duplicate "string" value in the dtype enum at line 3677 have both been resolved. The enum now correctly uses "date" as the first value.

Also applies to: 3675-3678

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
public/openapi/management-api.json (2)

817-820: Optional: align Report.timestamp wording with other Unix timestamp fields

You describe this as "Unix timestamp", while elsewhere (e.g. auth token fields) you use "Unix timestamp (seconds)". If this is also seconds, consider mirroring that phrasing for consistency; if it differs, calling out the unit explicitly would help clients.


825-838: Shared ReportData schema and stricter Report shape look good; just verify enum/requireds and consider a bit more docs

Moving Report.data.items to #/components/schemas/ReportData and setting additionalProperties: false is a nice tightening of the contract, and adding "date" plus deduplicating the enum values on dtype better reflects actual usage.

A couple of follow‑ups to consider:

  • Report.required = ["key", "participantID", "timestamp"] is a stronger guarantee than before; please double‑check that all existing responses (including legacy data) always include these three fields so the schema does not over‑promise.
  • Adding "date" to the dtype enum is an expansion; generated clients that modeled the old enum as a closed set may need to be regenerated. If this field has been returning "date" in production already, it would be good to call that out in changelog/release notes.
  • For ReportData, a short description on key, value, and especially dtype (including how non‑string dtypes like int, float, date, rawMessage, keyList are encoded into the string value) would make the schema much more self‑explanatory to client authors.

Also applies to: 840-851

public/openapi/participant-api.json (1)

3619-3637: Consider adding required fields to PaginationInfos.

The PaginationInfos schema properly constrains the structure with explicit properties and additionalProperties: false, but all fields are optional. Pagination metadata typically requires these fields to be meaningful to clients.

🔎 Suggested improvement
                "pageSize": {
                    "type": "integer"
                }
                },
+               "required": [
+                   "totalCount",
+                   "currentPage",
+                   "totalPages",
+                   "pageSize"
+               ],
                "additionalProperties": false
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between caa4359 and e03c6ac.

📒 Files selected for processing (2)
  • public/openapi/management-api.json (3 hunks)
  • public/openapi/participant-api.json (2 hunks)
🔇 Additional comments (2)
public/openapi/management-api.json (1)

804-807: Clarified Report.id description is consistent and helpful

Using "MongoDB ObjectID as hex string" matches other schemas (e.g. ManagementUser.id) and makes the wire format unambiguous. No further changes needed here.

public/openapi/participant-api.json (1)

3643-3688: Excellent schema definition with proper constraints.

The Report schema is well-structured with:

  • Explicit property definitions and helpful descriptions
  • Appropriate type constraints (integer for timestamp, date-time format for modifiedAt)
  • Required fields for core identifiers (key, participantID, timestamp)
  • Strict validation with additionalProperties: false

This significantly improves API contract clarity compared to the previous permissive schema.

Comment thread public/openapi/participant-api.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
public/openapi/participant-api.json (1)

3668-3682: Add constraints on Report.data array items.

The data array items lack structural constraints: no required fields and no additionalProperties setting at the items level. This allows empty objects or objects with arbitrary properties in the array, undermining the strict schema approach used elsewhere in this PR.

🔎 Recommended fix to enforce item structure
                    "data": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": { "type": "string" },
                                "value": { "type": "string" },
                                "dtype": { 
                                    "type": "string", 
                                    "enum": ["date", "float", "int", "string", "rawMessage", "keyList"]
                                }
-                           }
+                           },
+                           "required": ["key", "value", "dtype"],
+                           "additionalProperties": false
                        }
                    }
🧹 Nitpick comments (1)
public/openapi/management-api.json (1)

804-838: Confirm if data should be required on Report

You’ve now closed Report (additionalProperties: false) and marked key, participantID, and timestamp as required, but not data. If the backend rejects reports without any data, the schema will be more accurate and consumer-friendly if data is also required.

If empty data is allowed, this is fine as-is; otherwise, consider:

Proposed change to make data required (if aligned with backend)
       "description": "Report object",
-      "required": [
-          "key",
-          "participantID",
-           "timestamp"
-        ]
+      "required": [
+        "key",
+        "participantID",
+        "timestamp",
+        "data"
+      ]
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e03c6ac and d596aff.

📒 Files selected for processing (2)
  • public/openapi/management-api.json
  • public/openapi/participant-api.json
🔇 Additional comments (1)
public/openapi/participant-api.json (1)

3619-3637: LGTM! Schema properly tightened.

The PaginationInfos schema now explicitly defines all properties with appropriate integer types and closes the object with additionalProperties: false, preventing arbitrary fields. This aligns with the PR's goal of providing more detailed schemas.

Comment thread public/openapi/management-api.json
Comment thread public/openapi/participant-api.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
public/openapi/management-api.json (2)

804-838: Report schema looks good; consider marking response-only fields as read‑only / clarifying redundancy

The Report definition is now much clearer (id description, explicit timestamp, data as ReportData[], and required core fields). Two optional refinements you might consider later:

  • Mark fields that are response-only (e.g. id, possibly modifiedAt) as "readOnly": true so client SDKs don’t expect them on create/update payloads.
  • Since participantID is already in the path for /participants/{participantID}/reports, decide whether you really want it required in the body as well, or if it should be documented as redundant/ignored when mismatching.

Both are non-breaking documentation polish items and can be deferred.


840-850: Tighten ReportData contract (required fields and value typing) for better tooling

ReportData is now a closed object with explicit key, value, and dtype enum, which is a big improvement. Two follow-ups you might want to add:

  • Make the structure explicit by requiring these fields:
Optional required clause
       "ReportData": {
         "type": "object",
         "properties": {
           "key": { "type": "string" },
           "value": { "type": "string" },
           "dtype": { 
             "type": "string", 
             "enum": ["date", "float", "int", "string", "rawMessage", "keyList"]
           }  
         },
-        "additionalProperties": false
+        "additionalProperties": false,
+        "required": ["key", "value", "dtype"]
       },
  • Optionally clarify in a description whether value is always a string representation (even for float/int/date) or consider a more precise oneOf typing similar to StudyVariables.value if you want strict type guarantees.

These are schema-hardening/documentation improvements, not blockers.

📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d596aff and 7efb892.

📒 Files selected for processing (2)
  • public/openapi/management-api.json
  • public/openapi/participant-api.json
🚧 Files skipped from review as they are similar to previous changes (1)
  • public/openapi/participant-api.json

@phev8 phev8 merged commit 1978a40 into case-framework:main Dec 22, 2025
1 check passed
@kschneider84 kschneider84 deleted the api-docs branch January 7, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants