Skip to content

feat(api): create custom exercises - #68

Merged
rd-code-23 merged 1 commit into
mainfrom
feature/custom-exercise-create
Aug 25, 2026
Merged

rd-code-23 merged 1 commit into
mainfrom
feature/custom-exercise-create

Conversation

@rd-code-23

Copy link
Copy Markdown
Owner

Summary

Adds authenticated custom-exercise creation through POST /exercises.

A record created through this endpoint is always custom because its owner is always the authenticated user. Built-in exercises continue to be created only through the controlled seed process and have no owner.

Closes #67.

What changed

  • Added a shared createExerciseInputSchema and inferred CreateExerciseInput type.
  • Added authenticated POST /exercises routing.
  • Added database insertion for user-owned exercises.
  • Wired the new service operation into the API composition root.
  • Added focused contract, route, and service tests.

Request and response

The endpoint accepts only:

{
  "name": "Cable Fly",
  "description": "Keep the movement controlled."
}

description is optional and may be null. Input strings are trimmed. Names are limited to 100 characters and descriptions to 1,000 characters.

A successful request returns 201 Created with the browser-safe exercise summary:

{
  "id": "generated-uuid",
  "name": "Cable Fly",
  "description": "Keep the movement controlled.",
  "isCustom": true
}

Ownership and security

The client cannot supply ownership. The input schema is strict and rejects extra fields such as ownerUserId.

The request flow is:

  1. Authentication middleware requires a valid server-side session.
  2. The route validates and normalizes the request body.
  3. The authenticated user ID is read from the session.
  4. The service inserts that user ID as owner_user_id.
  5. The API returns the shared browser-safe exercise shape.

Even if a user creates an exercise with the same name as a built-in exercise, the newly created record is custom because isCustom represents record ownership, not whether its name appears in the built-in catalog.

Error behavior

  • Anonymous request: 401 authentication_required
  • Invalid or client-expanded request body: 400 invalid_request
  • Unexpected database or server failure: existing safe 500 internal_server_error handling

Verification

  • Type-checking passed.
  • ESLint passed.
  • Full test suite passed: 78 tests.
  • Focused exercise tests passed: 11 contract, route, and service tests.
  • Changed files pass Prettier.

Out of scope

  • Updating or deleting custom exercises
  • Duplicate-name prevention
  • Exercise images
  • Search and pagination
  • Routine creation

@rd-code-23
rd-code-23 merged commit bf7026f into main Aug 25, 2026
1 check passed
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.

[Routines][Phase 2] Create custom exercise endpoint

1 participant