@@ -157,3 +157,297 @@ pub struct UpdateUserRequest {
157157 pub name : Option < String > ,
158158 pub email : Option < String > ,
159159}
160+
161+ /// Versioned health API for testing version evolution.
162+ pub mod versioned_health {
163+ use super :: * ;
164+ use dropshot_api_manager_types:: api_versions;
165+
166+ api_versions ! (
167+ [ ( 3 , WITH_METRICS ) , ( 2 , WITH_DETAILED_STATUS ) , ( 1 , INITIAL ) , ]
168+ ) ;
169+
170+ #[ dropshot:: api_description]
171+ pub trait VersionedHealthApi {
172+ type Context ;
173+
174+ /// Check if the service is healthy (all versions).
175+ #[ endpoint {
176+ method = GET ,
177+ path = "/health" ,
178+ operation_id = "health_check" ,
179+ versions = "1.0.0" ..
180+ } ]
181+ async fn health_check (
182+ rqctx : RequestContext < Self :: Context > ,
183+ ) -> Result < HttpResponseOk < HealthStatusV1 > , HttpError > ;
184+
185+ /// Get detailed health status (v2+).
186+ #[ endpoint {
187+ method = GET ,
188+ path = "/health/detailed" ,
189+ operation_id = "detailed_health_check" ,
190+ versions = "2.0.0" ..
191+ } ]
192+ async fn detailed_health_check (
193+ rqctx : RequestContext < Self :: Context > ,
194+ ) -> Result < HttpResponseOk < DetailedHealthStatus > , HttpError > ;
195+
196+ /// Get service metrics (v3+).
197+ #[ endpoint {
198+ method = GET ,
199+ path = "/metrics" ,
200+ operation_id = "get_metrics" ,
201+ versions = "3.0.0" ..
202+ } ]
203+ async fn get_metrics (
204+ rqctx : RequestContext < Self :: Context > ,
205+ ) -> Result < HttpResponseOk < ServiceMetrics > , HttpError > ;
206+ }
207+
208+ /// Basic health status response (v1).
209+ #[ derive( JsonSchema , Serialize ) ]
210+ pub struct HealthStatusV1 {
211+ pub status : String ,
212+ pub timestamp : DateTime < Utc > ,
213+ }
214+
215+ /// Detailed health status response (v2+).
216+ #[ derive( JsonSchema , Serialize ) ]
217+ pub struct DetailedHealthStatus {
218+ pub status : String ,
219+ pub timestamp : DateTime < Utc > ,
220+ pub uptime_seconds : u64 ,
221+ pub dependencies : Vec < DependencyStatus > ,
222+ }
223+
224+ /// Dependency status information.
225+ #[ derive( JsonSchema , Serialize ) ]
226+ pub struct DependencyStatus {
227+ pub name : String ,
228+ pub status : String ,
229+ pub response_time_ms : Option < u64 > ,
230+ }
231+
232+ /// Service metrics response (v3+).
233+ #[ derive( JsonSchema , Serialize ) ]
234+ pub struct ServiceMetrics {
235+ pub requests_per_second : f64 ,
236+ pub error_rate : f64 ,
237+ pub avg_response_time_ms : f64 ,
238+ pub active_connections : u32 ,
239+ }
240+ }
241+
242+ /// Versioned user API for testing complex schema evolution.
243+ pub mod versioned_user {
244+ use super :: * ;
245+ use dropshot_api_manager_types:: api_versions;
246+
247+ api_versions ! ( [
248+ ( 3 , WITH_ROLES_AND_PERMISSIONS ) ,
249+ ( 2 , WITH_PROFILE_DATA ) ,
250+ ( 1 , INITIAL ) ,
251+ ] ) ;
252+
253+ #[ dropshot:: api_description]
254+ pub trait VersionedUserApi {
255+ type Context ;
256+
257+ /// List all users (all versions).
258+ #[ endpoint {
259+ method = GET ,
260+ path = "/users" ,
261+ operation_id = "list_users" ,
262+ versions = "1.0.0" ..VERSION_WITH_PROFILE_DATA
263+ } ]
264+ async fn list_users_v1 (
265+ rqctx : RequestContext < Self :: Context > ,
266+ query : Query < ListUsersQueryV1 > ,
267+ ) -> Result < HttpResponseOk < UserListV1 > , HttpError > ;
268+
269+ /// List all users with profile data (v2+).
270+ #[ endpoint {
271+ method = GET ,
272+ path = "/users" ,
273+ operation_id = "list_users" ,
274+ versions = "2.0.0" ..
275+ } ]
276+ async fn list_users_v2 (
277+ rqctx : RequestContext < Self :: Context > ,
278+ query : Query < ListUsersQueryV2 > ,
279+ ) -> Result < HttpResponseOk < UserListV2 > , HttpError > ;
280+
281+ /// Get a specific user by ID (all versions).
282+ #[ endpoint {
283+ method = GET ,
284+ path = "/users/{id}" ,
285+ operation_id = "get_user" ,
286+ versions = "1.0.0" ..VERSION_WITH_PROFILE_DATA
287+ } ]
288+ async fn get_user_v1 (
289+ rqctx : RequestContext < Self :: Context > ,
290+ path : Path < UserIdPath > ,
291+ ) -> Result < HttpResponseOk < UserV1 > , HttpError > ;
292+
293+ /// Get a specific user by ID with profile data (v2+).
294+ #[ endpoint {
295+ method = GET ,
296+ path = "/users/{id}" ,
297+ operation_id = "get_user" ,
298+ versions = "2.0.0" ..
299+ } ]
300+ async fn get_user_v2 (
301+ rqctx : RequestContext < Self :: Context > ,
302+ path : Path < UserIdPath > ,
303+ ) -> Result < HttpResponseOk < UserV2 > , HttpError > ;
304+
305+ /// Create a new user (v1 only).
306+ #[ endpoint {
307+ method = POST ,
308+ path = "/users" ,
309+ operation_id = "create_user" ,
310+ versions = "1.0.0" ..VERSION_WITH_PROFILE_DATA
311+ } ]
312+ async fn create_user_v1 (
313+ rqctx : RequestContext < Self :: Context > ,
314+ body : TypedBody < CreateUserRequestV1 > ,
315+ ) -> Result < HttpResponseOk < UserV1 > , HttpError > ;
316+
317+ /// Create a new user with profile data (v2+).
318+ #[ endpoint {
319+ method = POST ,
320+ path = "/users" ,
321+ operation_id = "create_user" ,
322+ versions = "2.0.0" ..
323+ } ]
324+ async fn create_user_v2 (
325+ rqctx : RequestContext < Self :: Context > ,
326+ body : TypedBody < CreateUserRequestV2 > ,
327+ ) -> Result < HttpResponseOk < UserV2 > , HttpError > ;
328+
329+ /// Assign role to user (v3+).
330+ #[ endpoint {
331+ method = PUT ,
332+ path = "/users/{id}/role" ,
333+ operation_id = "assign_user_role" ,
334+ versions = "3.0.0" ..
335+ } ]
336+ async fn assign_user_role (
337+ rqctx : RequestContext < Self :: Context > ,
338+ path : Path < UserIdPath > ,
339+ body : TypedBody < AssignRoleRequest > ,
340+ ) -> Result < HttpResponseOk < UserV2 > , HttpError > ;
341+
342+ /// List user permissions (v3+).
343+ #[ endpoint {
344+ method = GET ,
345+ path = "/users/{id}/permissions" ,
346+ operation_id = "list_user_permissions" ,
347+ versions = "3.0.0" ..
348+ } ]
349+ async fn list_user_permissions (
350+ rqctx : RequestContext < Self :: Context > ,
351+ path : Path < UserIdPath > ,
352+ ) -> Result < HttpResponseOk < UserPermissions > , HttpError > ;
353+ }
354+
355+ /// Query parameters for listing users (v1).
356+ #[ derive( JsonSchema , Deserialize ) ]
357+ pub struct ListUsersQueryV1 {
358+ pub limit : Option < u32 > ,
359+ pub offset : Option < u32 > ,
360+ }
361+
362+ /// Query parameters for listing users (v2+).
363+ #[ derive( JsonSchema , Deserialize ) ]
364+ pub struct ListUsersQueryV2 {
365+ pub limit : Option < u32 > ,
366+ pub offset : Option < u32 > ,
367+ pub email_filter : Option < String > ,
368+ pub include_inactive : Option < bool > ,
369+ }
370+
371+ /// User information (v1).
372+ #[ derive( JsonSchema , Serialize ) ]
373+ pub struct UserV1 {
374+ pub id : u32 ,
375+ pub name : String ,
376+ pub email : String ,
377+ pub created_at : DateTime < Utc > ,
378+ }
379+
380+ /// User information with profile data (v2+).
381+ #[ derive( JsonSchema , Serialize ) ]
382+ pub struct UserV2 {
383+ pub id : u32 ,
384+ pub name : String ,
385+ pub email : String ,
386+ pub created_at : DateTime < Utc > ,
387+ pub updated_at : DateTime < Utc > ,
388+ pub profile : UserProfile ,
389+ pub is_active : bool ,
390+ pub role : Option < String > , // Added in v3 but wire-compatible.
391+ }
392+
393+ /// User profile information (v2+).
394+ #[ derive( JsonSchema , Serialize ) ]
395+ pub struct UserProfile {
396+ pub bio : Option < String > ,
397+ pub avatar_url : Option < String > ,
398+ pub timezone : Option < String > ,
399+ pub preferred_language : Option < String > ,
400+ }
401+
402+ /// List of users response (v1).
403+ #[ derive( JsonSchema , Serialize ) ]
404+ pub struct UserListV1 {
405+ pub users : Vec < UserV1 > ,
406+ pub total_count : u32 ,
407+ }
408+
409+ /// List of users response (v2+).
410+ #[ derive( JsonSchema , Serialize ) ]
411+ pub struct UserListV2 {
412+ pub users : Vec < UserV2 > ,
413+ pub total_count : u32 ,
414+ pub has_more : bool ,
415+ }
416+
417+ /// Request to create a new user (v1).
418+ #[ derive( JsonSchema , Deserialize ) ]
419+ pub struct CreateUserRequestV1 {
420+ pub name : String ,
421+ pub email : String ,
422+ }
423+
424+ /// Request to create a new user with profile (v2+).
425+ #[ derive( JsonSchema , Deserialize ) ]
426+ pub struct CreateUserRequestV2 {
427+ pub name : String ,
428+ pub email : String ,
429+ pub profile : Option < CreateUserProfile > ,
430+ }
431+
432+ /// Profile data for user creation (v2+).
433+ #[ derive( JsonSchema , Deserialize ) ]
434+ pub struct CreateUserProfile {
435+ pub bio : Option < String > ,
436+ pub timezone : Option < String > ,
437+ pub preferred_language : Option < String > ,
438+ }
439+
440+ /// Request to assign role to user (v3+).
441+ #[ derive( JsonSchema , Deserialize ) ]
442+ pub struct AssignRoleRequest {
443+ pub role : String ,
444+ }
445+
446+ /// User permissions response (v3+).
447+ #[ derive( JsonSchema , Serialize ) ]
448+ pub struct UserPermissions {
449+ pub user_id : u32 ,
450+ pub role : String ,
451+ pub permissions : Vec < String > ,
452+ }
453+ }
0 commit comments