# Next-gen Walk REST APIs (headless, under `walk/v1/...`).
# Same Pulse servlet base as MyWork next-gen: /MYWORK/service/
openapi: 3.0.3
info:
  title: TM Next-Gen — Walk execution
  description: |
    OpenAPI for the Walk execution APIs (`walk/v1/...`).

    Same server base URL as WALK next-gen and legacy specs: `/MYWORK/service/`.

    Query and form fields are generally **snake_case**; the server normalizes to camelCase internally.

    **Authentication:** All endpoints require the `X-reflexis-csrf-token-X` header carrying a valid
    session token. Session-derived identity fields (`domain_id`, `user_id`, `unit_id`, `dept_id`,
    `profile_id`, `time_zone_long`, `lang_code`) are **not** accepted as request parameters — they
    are always resolved from the validated session.

    Companion spec: `task-execution/next-gen-task-execution-api.yaml`. Use Swagger UI definition dropdown to switch modules.

    ---

    ## Error Codes Reference (Walk APIs)

    Session validation uses **shared** error codes (same family as MyWork). Walk-specific validation uses
    **Walk** codes. Structured failures return JSON with `status`, `errorCode`, and `response` for HTTP 4xx/5xx.
    Business-rule failures often return HTTP **200** with `status: "ER"` and an `error` field (string or structured)
    — **no** `errorCode`.

    **Note:** The code `E202` appears for **invalid user session** (HTTP 401) and **invalid instance / model access**
    (HTTP 403). Use HTTP status to tell them apart.

    ### Session / token

    | Code | HTTP | Description |
    |---|---|---|
    | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
    | `E101` | 400 | Domain id is mandatory (invalid session payload) |
    | `E202` | 401 | User session is invalid (empty user id after token parse) |
    | `E204` | 401 | Invalid or expired token |

    ### Typical walk validation and server errors

    | Code | HTTP | Description |
    |---|---|---|
    | `E110` | 400 | Missing required parameter (placeholder `{0}` is the snake_case parameter name) |
    | `E108` | 500 | Walk name is mandatory |
    | `E109` | 500 | Walk description is mandatory |
    | `E301` | 500 | Walk name exceeds maximum length |
    | `E302` | 500 | Walk description exceeds maximum length |
    | `E202` | 403 | Invalid instance / model access (walk creation only) |
    | `E500` | 500 | Unhandled exception (message `"Unexpected server error."`) |

    ### Full walk error code catalog (reference)

    | Code | Description |
    |---|---|
    | `E101` | Domain id is mandatory |
    | `E102` | Auth token is mandatory |
    | `E103` | User id is mandatory |
    | `E104` | Profile id is mandatory |
    | `E105` | Department id is mandatory |
    | `E106` | Unit id is mandatory |
    | `E107` | Action type is mandatory |
    | `E108` | Walk name is mandatory |
    | `E109` | Walk description is mandatory |
    | `E110` | `{0}` is mandatory |
    | `E201` | User session is invalid (reserved walk code; session path typically uses `E202`) |
    | `E202` | Invalid instance access |
    | `E301` | Walk name length should not exceed `{0}` characters |
    | `E302` | Walk description length should not exceed `{0}` characters |
    | `E303` | Error while starting the walk |
    | `E304` | Error while scheduling the walk |
    | `E305` | Error while submitting the walk |
    | `E404` | No data found |
    | `E500` | Internal server error |

    `ER` is the `status` field value for error responses; it is not an `errorCode`.

    ---

    ## Common Response Envelope

    Successful responses use `status: OK` and a payload field named for the resource (e.g. `walk_categories`,
    `walks`, `walk_details`), not a generic `message` field.

    On **HTTP 200** application-level failure (business error envelope):

    ```json
    { "status": "ER", "error": "<details>" }
    ```

    On **HTTP 4xx/5xx** (structured validation / server error envelope):

    ```json
    { "status": "ER", "errorCode": "E110", "response": "<localized message>" }
    ```

  version: 1.0.0
  contact:
    name: API Support
    email: noreply@zebra.com

servers:
  - url: /MYWORK/service/
    description: Application context + Pulse servlet (typical deployment)
  - url: https://fs3.reflexisinc.com/MYWORK/service/
    description: Example development host
  - url: http://localhost:3001/MYWORK/service/
    description: Local CORS proxy — npm run cors-proxy
  - url: https://dev-api.zebra.com/
    description: Dev API APIGEE
  - url: https://api.zebra.com/
    description: API APIGEE

tags:
  - name: WalkCategories
    description: Walk category management — retrieve categories by optional ID filter
  - name: WalkList
    description: Walk list retrieval — adhoc, scheduled, incremental, and count-only modes
  - name: WalkDetail
    description: Single walk detail by `form_unique_id` (walk-id path parameter)
  - name: WalkCreate
    description: Start (create) a new walk instance — multipart/form-data POST
  - name: WalkSchedule
    description: Schedule a walk for distribution to stores — multipart/form-data POST
  - name: WalkSubmit
    description: Submit questionnaire answers for a walk instance — multipart/form-data POST
  - name: WalkQuestions
    description: Download questionnaire definition with optional pre-populated answers
  - name: WalkTypes
    description: Retrieve available walk types scoped by permit type, schedule type, and offline flag
  - name: WalkStores
    description: Distribution store list for walk scheduling — scoped by model and action type
  - name: WalkUsers
    description: User list for walk assignment — scoped by profile, unit, department, and org level
  - name: WalkPermissions
    description: Permission evaluation for a walk entity — scoped by entity ID and permit type

security:
  - AuthTokenHeader: []

components:
  securitySchemes:
    AuthTokenHeader:
      type: apiKey
      in: header
      name: X-reflexis-csrf-token-X
      description: |
        Session authentication token validated server-side against the user session store.
        Required on **every** request. Absence returns HTTP 400; invalid/expired token returns HTTP 401.

  parameters:
    WalkId:
      name: walk-id
      in: path
      required: true
      description: |
        `form_unique_id` of the walk instance. Obtained from `GET /walk/v1/walks/` or
        `GET /walk/v1/walks/scheduled` response list. Must not be blank.
      schema:
        type: string

    # ─── Common pagination / fetch parameters ───────────────────────────────
    NoOfRecords:
      name: no_of_records
      in: query
      required: false
      description: |
        **Default:** `20`

        Maximum number of records to return in the response. Combined with `reference_data`
        for cursor-based pagination. Pass a higher value to fetch more records in a single call.
      schema:
        type: integer
        default: 20
        minimum: 1
        example: 20

    CutOffTime:
      name: cut_off_time
      in: query
      required: false
      description: |
        **Default:** `0` (no cutoff)

        Epoch time in **milliseconds** used as an upper-bound cutoff for date filtering.
        Records with a walk date **after** this timestamp are excluded. Pass `0` to disable.
      schema:
        type: integer
        format: int64
        default: 0
        example: 1713657600000

    LastFetch:
      name: last_fetch
      in: query
      required: false
      description: |
        **Default:** `"0"` (no incremental filtering)

        Epoch time in **milliseconds** from the previous sync. Only used when `latest_fetch=Y`.
        When set, the server returns only records modified since this timestamp (delta/incremental fetch).
      schema:
        type: string
        default: "0"
        example: "1713571200000"

    LatestFetch:
      name: latest_fetch
      in: query
      required: false
      description: |
        **Default:** `N`

        Controls incremental fetch mode:
        - `Y` — enable incremental fetch; `last_fetch` is used as the lower-bound timestamp
        - `N` — regular (full) fetch; `last_fetch` is ignored
      schema:
        type: string
        default: "N"
        enum: ["Y", "N"]

    ReferenceData:
      name: reference_data
      in: query
      required: false
      description: |
        Opaque cursor token returned from the previous response. Supply this to retrieve the
        next page of results without re-fetching already-returned records. Omit on the first call.
      schema:
        type: string

    # ─── Common filter / sort parameters ────────────────────────────────────
    WalkStatus:
      name: status
      in: query
      required: false
      description: |
        Comma-separated walk status code filter. When omitted, all statuses are returned.

        | Code | Description |
        |---|---|
        | `N`  | Not Started |
        | `I`  | In Progress |
        | `PA` | Pending Authorize |
        | `PR` | Pending Review |
        | `PP` | Pending Publish |
        | `A`  | Active |
        | `RC` | Recall |
        | `R`  | Rejected |
        | `WD` | Withdrawn |
        | `X`  | Discard |
        | `EX` | Expired |
      schema:
        type: string

    SortBy:
      name: sort_by
      in: query
      required: false
      description: |
        Comma-separated field names to sort by. Applies in left-to-right priority.
        Supported fields vary by endpoint (e.g. `walkStartDate`, `creationTime`, `title`).
      schema:
        type: string

    SortOrder:
      name: sort_order
      in: query
      required: false
      description: |
        Comma-separated sort direction values, positionally matching `sort_by`.
        - `A` — Ascending
        - `D` — Descending
      schema:
        type: string
        enum: ["A", "D"]

    ClaimFlag:
      name: claim_flag
      in: query
      required: false
      description: |
        **Default:** `N`

        Controls whether to filter by walk claim status:
        - `Y` — return claimed walks only
        - `N` — include non-claimed walks (based on current view context)
      schema:
        type: string
        default: "N"
        enum: ["Y", "N"]

    WalkType:
      name: walk_type
      in: query
      required: false
      description: Walk template/model identifier filter. When supplied, limits results to walks
        of the specified walk type/model.
      schema:
        type: string

    WalkStartDate:
      name: start_date
      in: query
      required: false
      description: |
        Start date lower bound for the walk visibility window.
        **Format:** `yyyyMMdd` (e.g. `20260421`). When omitted, no lower-bound date filter is applied.
      schema:
        type: string
        pattern: '^\d{8}$'
        example: "20260421"

    WalkEndDate:
      name: end_date
      in: query
      required: false
      description: |
        End date upper bound for the walk visibility window.
        **Format:** `yyyyMMdd` (e.g. `20260430`). When omitted, no upper-bound date filter is applied.
      schema:
        type: string
        pattern: '^\d{8}$'
        example: "20260430"

  schemas:
    JsonObject:
      type: object
      additionalProperties: true
      description: Generic JSON object — structure varies by endpoint and config type.

    WalkApiSuccessResponse:
      type: object
      description: |
        Successful response envelope for Walk APIs.

        **Named key (most GET endpoints):** `{ "status": "OK", "<resource_key>": <payload> }` — e.g. `walk_categories`,
        `walks`, `scheduled_walks`, `walk_types`, `walk_questions`, `walk_stores`, `walk_details`, `walk_permissions`,
        `walk_users`. There is **no** `message` property.

        **Default key (multipart POST — create / schedule / submit):** `{ "status": "OK", "response": <object> }`.

        Nested objects and arrays are emitted in **snake_case** (internal camelCase field names are normalized in responses).
      properties:
        status:
          type: string
          enum: [OK]
        response:
          $ref: '#/components/schemas/JsonObject'
        walk_categories:
          type: array
          items:
            $ref: '#/components/schemas/WalkCategory'
        walks:
          $ref: '#/components/schemas/JsonObject'
        scheduled_walks:
          $ref: '#/components/schemas/JsonObject'
        walk_types:
          type: array
          items: {}
        walk_questions:
          $ref: '#/components/schemas/JsonObject'
        walk_stores:
          $ref: '#/components/schemas/JsonObject'
        walk_details:
          $ref: '#/components/schemas/JsonObject'
        walk_permissions:
          $ref: '#/components/schemas/JsonObject'
        walk_users:
          type: array
          items: {}
      required: [status]
      additionalProperties: true
      example:
        status: OK
        walks:
          walk_list: []
          last_fetch_time: 1710000000000

    WalkApiErrorResponse:
      type: object
      description: |
        Error envelope shape depends on how the error is produced:

        - **HTTP 200** — business or validation failure after the request is accepted:
          `{ "status": "ER", "error": "<string or JSON>" }` (no `errorCode`).
        - **HTTP 4xx/5xx** — structured API error:
          `{ "status": "ER", "errorCode": "<code>", "response": "<localized message>" }`.

        See the global **Error Codes Reference** in this spec for `errorCode` values.
      properties:
        status:
          type: string
          enum: [ER]
        errorCode:
          type: string
          description: Structured error code (Walk or shared session codes; see **Error Codes Reference**).
        response:
          type: string
          description: Human-readable message when `errorCode` is present (HTTP 4xx/5xx responses).
        error:
          description: Payload for HTTP 200 error bodies (string, array, or object).
          oneOf:
            - type: string
            - type: array
              items: {}
            - type: object
              additionalProperties: true
      required: [status]
      example:
        status: ER
        errorCode: E110
        response: "model_id is mandatory"

    WalkCategory:
      type: object
      description: A single walk category object.
      properties:
        domain_id:
          type: integer
          description: Domain identifier for the category.
        category_name:
          type: string
          description: Display name of the walk category.
        category_id:
          type: string
          description: Unique category identifier.
        category_type:
          type: string
          description: Category type code (e.g. `"W"` for walk).
        category_desc:
          type: string
          description: Category description.
        creator_name:
          type: string
          description: Username of the category creator.
        permission:
          type: string
          description: Comma-separated permission flags (e.g. `"1,1,1,1"`).
        created_by:
          type: string
          description: Login ID of the creator.

  responses:
    Unauthorized:
      description: Missing or invalid `X-reflexis-csrf-token-X` session token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalkApiErrorResponse'
          examples:
            missingHeader:
              summary: Header not sent
              value:
                status: ER
                errorCode: E112
                response: "X-reflexis-csrf-token-X header is mandatory"
            expiredToken:
              summary: Token invalid or expired
              value:
                status: ER
                errorCode: E204
                response: "Invalid or expired token"
            invalidSession:
              summary: User id missing after token parse
              value:
                status: ER
                errorCode: E202
                response: "User session is invalid"

    BadRequest:
      description: Invalid or missing required request parameter.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalkApiErrorResponse'
          example:
            status: ER
            errorCode: E110
            response: "entity_id is mandatory"

    NotFound:
      description: |
        Not used by the Walk detail endpoint for “not found”; those cases return HTTP 200 with
        `status: "ER"` and an `error` field. Reserved for gateway or proxy behavior.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalkApiErrorResponse'
          example:
            status: ER
            error: "Walk not found for the given walk-id"

    InternalServerError:
      description: Unexpected server-side error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalkApiErrorResponse'
          example:
            status: ER
            errorCode: E500
            response: "Unexpected server error."

paths:
  # ---------------------------------------------------------------------------
  # Walk Categories (/walk/v1/categories)
  # ---------------------------------------------------------------------------
  /walk/v1/categories:
    get:
      tags: [WalkCategories]
      summary: List walk categories (optionally filtered by category_id)
      operationId: getWalkCategories
      description: |
        Returns walk categories visible to the authenticated user. Optionally filter to a
        single category by passing `category_id`. When omitted, all accessible categories
        for the user's domain and profile are returned.

        **Authentication:** `X-reflexis-csrf-token-X` required. Domain and user context are
        resolved from the session — not accepted as query parameters.

        ---

        ## Response Structure

        ```json
        {
          "walk_categories": [
            {
              "domain_id": 170010099,
              "category_name": "Store Audit",
              "category_id": "111",
              "category_type": "W",
              "category_desc": "Monthly store audit checklist",
              "creator_name": "SYSADMIN",
              "permission": "1,1,1,1",
              "created_by": "SYSADMIN"
            }
          ],
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_categories` | Array of category objects |
        | `walk_categories[*].domain_id` | Domain the category belongs to |
        | `walk_categories[*].category_id` | Unique category identifier |
        | `walk_categories[*].category_name` | Display name |
        | `walk_categories[*].category_type` | Type code (`W` = Walk) |
        | `walk_categories[*].category_desc` | Full description |
        | `walk_categories[*].creator_name` | Display name of creator |
        | `walk_categories[*].permission` | Comma-separated permission flags |
        | `walk_categories[*].created_by` | Login ID of creator |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request...` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: category_id
          in: query
          required: false
          description: |
            **Applies to:** Single-category lookup.

            Category identifier used to filter returned walk categories. When supplied, only the
            matching category is returned. When omitted, all categories accessible to the user's
            domain and profile are returned.
          schema:
            type: string

      responses:
        '200':
          description: |
            Success — returns `walk_categories` array (may be empty if no categories match).
            Application-level errors also return HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    properties:
                      walk_categories:
                        type: array
                        items:
                          $ref: '#/components/schemas/WalkCategory'
                      status:
                        type: string
                        enum: [OK]
                    required: [walk_categories, status]
                  - $ref: '#/components/schemas/WalkApiErrorResponse'
              examples:
                success:
                  summary: Successful response
                  value:
                    walk_categories:
                      - domain_id: 170010099
                        category_name: "Store Audit"
                        category_id: "111"
                        category_type: "W"
                        category_desc: "Monthly store audit checklist"
                        creator_name: "SYSADMIN"
                        permission: "1,1,1,1"
                        created_by: "SYSADMIN"
                    status: OK
                error:
                  summary: Application error
                  value:
                    status: ER
                    error: "Error while processing request."
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk List + Create (/walk/v1/walks/)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/:
    get:
      tags: [WalkList]
      summary: List walk instances (with filtering, pagination, and sort)
      operationId: getWalks
      description: |
        Returns a paginated list of walk instances visible to the authenticated user.
        Supports filtering by status, date range, walk type, category, store unit, schedule type,
        and view scope. Use `walk_count=Y` to retrieve only the total record count without payload.

        **Pagination:** Uses `no_of_records` + `reference_data` cursor pattern.
        Supply the `reference_data` token returned from a previous response to fetch the next page.

        **Incremental fetch:** Set `latest_fetch=Y` and provide `last_fetch` (epoch ms) to
        retrieve only records modified since the previous sync.

        **Authentication:** `X-reflexis-csrf-token-X` required. Domain and user context are
        resolved from the session.

        ---

        ## Response Structure

        Success envelope: top-level **`walks`** object next to **`status`** (no `message`, no extra wrapper).

        Typical list payload includes **`walk_list`** (array), pagination **`reference_data`**, and **`last_fetch_time`**
        (all **snake_case** in JSON). Exact inner shape depends on filters and the walk list query.

        ```json
        {
          "walks": {
            "walk_list": [],
            "reference_data": "...",
            "last_fetch_time": 1710000000000
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walks` | JSON object returned by the walk list query |
        | `walks.walk_list` | Walk instance rows when returning a list (not count-only) |
        | `walks.reference_data` | Opaque cursor for the next page, when applicable |
        | `walks.last_fetch_time` | Server timestamp (epoch ms) for incremental sync |

        When query param **`walk_count=Y`**, the service returns a **count** inside `walks` (e.g. **`total_count`**
        — includes **`total_count`** (count-only mode), not a full `walk_list`:

        ```json
        {
          "walks": {
            "total_count": 42
          },
          "status": "OK"
        }
        ```

        ---

        ## Pagination

        | Parameter | Role |
        |---|---|
        | `no_of_records` | Page size (default `20`) |
        | `reference_data` | Opaque cursor — supply from previous response to get next page |

        ---

        ## View Types

        | Value | Description |
        |---|---|
        | `M` | My Walk — walks assigned to the authenticated user (default) |
        | `A` | All Walk — all walks visible in the user's domain/org |
        | `R` | Walk To Reopen — walks eligible for re-opening |

        ---

        ## Schedule Types

        | Value | Description |
        |---|---|
        | `A` | Adhoc (default) |
        | `R` | Repeating |
        | `S` | Scheduled |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - $ref: '#/components/parameters/NoOfRecords'
        - $ref: '#/components/parameters/CutOffTime'
        - $ref: '#/components/parameters/LastFetch'
        - $ref: '#/components/parameters/LatestFetch'
        - $ref: '#/components/parameters/WalkStatus'
        - $ref: '#/components/parameters/ClaimFlag'
        - $ref: '#/components/parameters/SortBy'
        - $ref: '#/components/parameters/SortOrder'
        - $ref: '#/components/parameters/WalkType'
        - $ref: '#/components/parameters/WalkStartDate'
        - $ref: '#/components/parameters/WalkEndDate'
        - $ref: '#/components/parameters/ReferenceData'

        - name: permit_type
          in: query
          required: false
          description: |
            Permission scope for filtering applicable walk templates.

            | Value | Description |
            |---|---|
            | `C` | Conduct — user can conduct this walk |
            | `S` | Schedule — user can schedule this walk |
            | `V` | View — user can view this walk |
          schema:
            type: string
            enum: [C, S, V]

        - name: title
          in: query
          required: false
          description: Partial-match filter for walk title/name. Case-insensitive substring search.
          schema:
            type: string

        - name: description
          in: query
          required: false
          description: Partial-match filter for walk description. Case-insensitive substring search.
          schema:
            type: string

        - name: view_type
          in: query
          required: false
          description: |
            **Default:** `M`

            View scope for walk list retrieval:
            - `M` — My Walk (walks assigned to the authenticated user)
            - `A` — All Walk (all walks visible in the domain)
            - `R` — Walk To Reopen (walks eligible for re-opening)
          schema:
            type: string
            default: "M"
            enum: [A, M, R]

        - name: offline_fetch
          in: query
          required: false
          description: |
            **Default:** `N`

            Offline content filter:
            - `Y` — return offline-enabled walks only
            - `N` — no offline-only filter (return all walks regardless of offline status)
          schema:
            type: string
            default: "N"
            enum: ["Y", "N"]

        - name: walk_count
          in: query
          required: false
          description: |
            **Default:** `N`

            Count-only mode:
            - `Y` — return total count of matching walks only (no payload list)
            - `N` — return full walk list payload with pagination
          schema:
            type: string
            default: "N"
            enum: ["Y", "N"]

        - name: filter_unit_id
          in: query
          required: false
          description: |
            Comma-separated assign-unit IDs to filter walk records. When supplied, only walks
            assigned to the specified units are returned.
          schema:
            type: string
            example: "1001,1002"

        - name: form_unique_id
          in: query
          required: false
          description: |
            Filter by a specific walk instance's `form_unique_id`. Returns the single matching
            walk instance when provided.
          schema:
            type: string

        - name: over_due_flag
          in: query
          required: false
          description: |
            Overdue filter flag:
            - `Y` — return overdue walks only (past due date with incomplete status)
            - `N` — do not apply overdue-only filter
          schema:
            type: string
            enum: ["Y", "N"]

        - name: filter_cat_type
          in: query
          required: false
          description: |
            Comma-separated category IDs used to filter walks. Only walks belonging to the
            specified categories are returned.
          schema:
            type: string

        - name: store_filter_params
          in: query
          required: false
          description: |
            JSON-encoded advanced store/unit filter criteria string. Provides fine-grained
            store-hierarchy filtering beyond `filter_unit_id`.
          schema:
            type: string

        - name: due_today_flag
          in: query
          required: false
          description: |
            Due-today filter flag:
            - `Y` — return walks due today only
            - `N` — do not apply due-today-only filter
          schema:
            type: string
            enum: ["Y", "N"]

        - name: schedule_type
          in: query
          required: false
          description: |
            Schedule type filter (no server-side default — when omitted all schedule types are considered):
            - `A` — Adhoc
            - `R` — Repeating
            - `S` — Scheduled
          schema:
            type: string
            enum: [A, R, S]

        - name: sort_by
          in: query
          required: false
          description: |
            **Default:** `walkStartDate`

            Comma-separated sort column(s). Common values: `walkStartDate`, `title`, `status`,
            `creationTime`. Pair with `sort_order` for direction.
          schema:
            type: string
            default: walkStartDate

        - name: sort_order
          in: query
          required: false
          description: |
            **Default:** `D`

            Comma-separated sort direction(s) matching `sort_by` positions:
            - `A` — Ascending
            - `D` — Descending
          schema:
            type: string
            default: "D"
            enum: [A, D]

      responses:
        '200':
          description: |
            Success — returns a **`walks`** object (`walk_list` for list mode, or e.g. **`total_count`**
            when `walk_count=Y`). Application-level errors are also returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk list response
                  value:
                    status: OK
                    walks:
                      walk_list: []
                      last_fetch_time: 1710000000000
                countOnly:
                  summary: Count-only response (walk_count=Y)
                  value:
                    status: OK
                    walks:
                      total_count: 42
                error:
                  summary: Application error
                  value:
                    status: ER
                    error: "Error while processing request."
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

    post:
      tags: [WalkCreate]
      summary: Start / create a new walk instance (multipart/form-data)
      operationId: createWalk
      description: |
        Creates and starts a new walk instance from the given model/category with schedule
        and assignment details. The request **must** be sent as `multipart/form-data`.

        All ten required fields must be present. Any missing required field returns HTTP 400
        with a validation error message listing the missing fields.

        **Authentication:** `X-reflexis-csrf-token-X` required. Domain and user context are
        resolved from the session.

        ---

        ## Request Headers

        | Header | Required | Description |
        |---|---|---|
        | `X-reflexis-csrf-token-X` | Yes | Session authentication token |
        | `Content-Type` | Yes | Must be `multipart/form-data` |

        ---

        ## Response Structure

        Success envelope with **`response`** wrapper only — shape is `{ "status": "OK", "response": <object> }`.

        For **start walk**, the response typically includes **`walk_list`** (array of walk rows)
        and related fields, all **snake_case** in JSON. There is **no** `message` property.

        ```json
        {
          "response": {
            "walk_list": []
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `response` | JSON object from start-walk processing (structure varies by branch) |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Missing required field | 400 | `<field_name> is mandatory` — each field is checked individually; first failure returns HTTP 400 with `errorCode: E110` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required multipart field (create-walk operation) |
        | `E108` | 500 | Walk name is mandatory |
        | `E109` | 500 | Walk description is mandatory |
        | `E301` | 500 | Walk name exceeds max length |
        | `E302` | 500 | Walk description exceeds max length |
        | `E202` | 403 | Invalid instance / model access |
        | `E500` | 500 | Unhandled server error |

      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              description: Walk creation form data. All properties marked as required must be present.
              properties:
                model_id:
                  type: string
                  description: |
                    **Required.** Walk template/model identifier. Obtained from `GET /walk/v1/walks/types`.
                category_id:
                  type: string
                  description: |
                    **Required.** Category identifier. Obtained from `GET /walk/v1/categories`.
                start_date:
                  type: string
                  description: |
                    **Required.** Walk start date. **Format:** `YYYY-MM-DD` (e.g. `2026-01-20`).
                  example: "2026-01-20"
                end_date:
                  type: string
                  description: |
                    **Required.** Walk end date. **Format:** `YYYY-MM-DD` (e.g. `2026-01-20`).
                  example: "2026-01-20"
                start_time:
                  type: string
                  description: |
                    **Required.** Walk start time. **Format:** `h:mm AM/PM` (e.g. `3:00 AM`).
                  example: "3:00 AM"
                walk_name:
                  type: string
                  description: "**Required.** Display name for the walk instance. Length-limited."
                  example: "Store Compliance Walk - Jan 2026"
                walk_description:
                  type: string
                  description: "**Required.** Description of the walk. Length-limited."
                  example: "Monthly compliance inspection for Store 1001"
                assign_unit:
                  type: string
                  description: "**Required.** Unit/store ID that the walk is assigned to."
                  example: "1001"
                assign_unit_time_zone:
                  type: string
                  description: |
                    **Required.** IANA time zone ID of the assigned unit.
                  example: "US/Eastern"
                assign_unit_name:
                  type: string
                  description: "**Required.** Display name of the assigned unit/store."
                  example: "Store 1001 - New York"
              required:
                - model_id
                - category_id
                - start_date
                - end_date
                - start_time
                - walk_name
                - walk_description
                - assign_unit
                - assign_unit_time_zone
                - assign_unit_name

      responses:
        '200':
          description: |
            Walk created. Returns **`response`** from start-walk processing (e.g. may contain `walk_list`).
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk created successfully
                  value:
                    status: OK
                    response:
                      walk_list: []
                validationError:
                  summary: First missing required field (HTTP 400)
                  description: |
                    This example is returned as **HTTP 400**, not HTTP 200.
                    Required-parameter validation fails on the first missing field using the
                    structured error body (`errorCode` + `response`).
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              examples:
                missingModelId:
                  summary: model_id missing
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
                invalidInstance:
                  summary: Invalid model instance access (E202, HTTP 403)
                  value:
                    status: ER
                    errorCode: E202
                    response: "Invalid Instance Access"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Scheduled Walks (/walk/v1/walks/scheduled)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/scheduled:
    get:
      tags: [WalkList]
      summary: List scheduled walks (with filtering, pagination, and sort)
      operationId: getScheduledWalks
      description: |
        Returns a paginated list of scheduled walk instances visible to the authenticated user.
        Supports filtering by status, date range, walk type, view scope, and incremental fetch.

        **Pagination:** Uses `no_of_records` + `reference_data` cursor pattern.

        **Incremental fetch:** Set `latest_fetch=Y` and provide `last_fetch` (epoch ms) to
        retrieve only records modified since the previous sync.

        **Authentication:** `X-reflexis-csrf-token-X` required. Domain and user context are
        resolved from the session.

        ---

        ## Response Structure

        Success envelope: top-level **`scheduled_walks`** next to **`status`**.

        Payload is a normalized **JSON object** from the scheduled-walk list query (typically includes **`walk_list`**,
        **`reference_data`**, **`last_fetch_time`** in snake_case). Shape varies by filters.

        ```json
        {
          "scheduled_walks": {
            "walk_list": [],
            "last_fetch_time": 1710000000000
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `scheduled_walks` | Scheduled walk list payload |
        | `scheduled_walks.walk_list` | Scheduled walk rows when present |

        ---

        ## Pagination

        | Parameter | Role |
        |---|---|
        | `no_of_records` | Page size (default `20`) |
        | `reference_data` | Opaque cursor — supply from previous response to get next page |

        ---

        ## View Types

        | Value | Description |
        |---|---|
        | `A` | All Walk — all scheduled walks visible in the domain (default) |
        | `R` | Walk To Reopen — scheduled walks eligible for re-opening |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: no_of_records
          in: query
          required: false
          description: |
            **Default:** `0` (no limit / all records)

            Maximum number of records to return. Unlike the adhoc walk list which defaults to `20`,
            `getScheduledWalks` defaults to `0` meaning **no server-side page limit** unless explicitly set.
          schema:
            type: integer
            default: 0
            minimum: 0
        - $ref: '#/components/parameters/CutOffTime'
        - $ref: '#/components/parameters/LastFetch'
        - $ref: '#/components/parameters/LatestFetch'
        - $ref: '#/components/parameters/WalkStatus'
        - $ref: '#/components/parameters/ClaimFlag'
        - $ref: '#/components/parameters/WalkType'
        - $ref: '#/components/parameters/WalkStartDate'
        - $ref: '#/components/parameters/WalkEndDate'
        - $ref: '#/components/parameters/ReferenceData'

        - name: sort_by
          in: query
          required: false
          description: |
            Comma-separated sort column(s). Common values: `creationTime`, `walkStartDate`, `title`,
            `status`. Pair with `sort_order` for direction. **No server-side default** — sort order
            is unspecified when omitted.
          schema:
            type: string

        - name: sort_order
          in: query
          required: false
          description: |
            **Default:** `D`

            Comma-separated sort direction(s) matching `sort_by` positions:
        - name: sort_order
          in: query
          required: false
          description: |
            Comma-separated sort direction(s) matching `sort_by` positions:
            - `A` — Ascending
            - `D` — Descending

            **No server-side default** — sort direction is unspecified when omitted.
          schema:
            type: string
            enum: [A, D]

        - name: title
          in: query
          required: false
          description: Partial-match filter for walk title/name. Case-insensitive substring search.
          schema:
            type: string

        - name: description
          in: query
          required: false
          description: Partial-match filter for walk description. Case-insensitive substring search.
          schema:
            type: string

        - name: view_type
          in: query
          required: false
          description: |
            **Default:** `A`

            View scope for scheduled walk list retrieval:
            - `A` — All Walk (all scheduled walks visible in the domain)
            - `R` — Walk To Reopen (scheduled walks eligible for re-opening)
          schema:
            type: string
            default: "A"
            enum: [A, R]

        - name: form_unique_id
          in: query
          required: false
          description: |
            Filter by a specific scheduled walk instance's `form_unique_id`. Returns the single
            matching walk when provided.
          schema:
            type: string

      responses:
        '200':
          description: |
            Success — returns **`scheduled_walks`** object (may include empty `walk_list`).
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Scheduled walk list
                  value:
                    status: OK
                    scheduled_walks:
                      walk_list: []
                      last_fetch_time: 1710000000000
                error:
                  summary: Application error
                  value:
                    status: ER
                    error: "Error while processing request."
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Types (/walk/v1/walks/types)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/types:
    get:
      tags: [WalkTypes]
      summary: List walk types available to the user (scoped by permit, schedule, and offline)
      operationId: getWalkTypes
      description: |
        Returns walk types (templates/models) available for the authenticated user based on
        permit type, schedule type, offline eligibility, and optional model/access-key scope.

        **Authentication:** `X-reflexis-csrf-token-X` required. Domain and profile context
        are resolved from the session.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_types`** (array or object; shape depends on the walk type list)
        next to **`status`**.

        ```json
        {
          "walk_types": [],
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_types` | Walk template/model entries (normalized to snake_case) |

        ---

        ## Permit Types

        | Value | Description |
        |---|---|
        | `C` | Conduct — user can conduct walks of this type (default) |
        | `S` | Schedule — user can schedule walks of this type |

        ---

        ## Schedule Types

        | Value | Description |
        |---|---|
        | `A` | Adhoc (default) |
        | `S` / `SA` | Scheduled |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: permit_type
          in: query
          required: false
          description: |
            **Default:** `C`

            Permit scope for filtering eligible walk types:
            - `C` — Conduct (user can conduct walks of this type)
            - `S` — Schedule (user can schedule walks of this type)
          schema:
            type: string
            default: "C"
            enum: [C, S]

        - name: schedule_type
          in: query
          required: false
          description: |
            **Default:** `A`

            Schedule category filter:
            - `A` — Adhoc
            - `S` or `SA` — Scheduled
          schema:
            type: string
            default: "A"
            enum: [A, S, SA]

        - name: fetch_offline
          in: query
          required: false
          description: |
            **Default:** `N`

            Offline walk type filter:
            - `Y` — return only offline-enabled walk types
            - `N` — no offline filter (return all eligible walk types)
          schema:
            type: string
            default: "N"
            enum: ["Y", "N"]

        - name: model_id
          in: query
          required: false
          description: |
            Optional walk template/model ID to scope returned walk types to a single model.
            When omitted, all eligible types are returned.
          schema:
            type: string

        - name: form_access_key
          in: query
          required: false
          description: |
            Form access key to resolve walk type eligibility for a specific walk instance context.
            Used in reopen/edit scenarios where the eligibility must be evaluated against an
            existing walk instance.
          schema:
            type: string

      responses:
        '200':
          description: |
            Success — returns `walk_types` array.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk types list
                  value:
                    status: OK
                    walk_types: []
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Questions (/walk/v1/walks/questions)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/questions:
    get:
      tags: [WalkQuestions]
      summary: Download questionnaire definition (with optional pre-populated answers)
      operationId: getWalkQuestions
      description: |
        Downloads the questionnaire definition for a walk template. When `form_trace_id` is
        supplied, the response includes pre-populated answers from the existing walk instance.

        `model_id` is **required**. `form_trace_id` is optional and
        is used to load a walk in progress (for resume or review scenarios).

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_questions`** holds the questionnaire **JSON object**
        from the questionnaire download (with answers merged when `form_trace_id` is set).

        The payload often has a **`response`** array; each element can contain **`model_data`** →
        **`question_data`** (internal names `response` / `modelData` / `questionData` map to snake_case in JSON).

        ```json
        {
          "walk_questions": {
            "response": [
              {
                "model_data": [
                  {
                    "question_data": []
                  }
                ]
              }
            ]
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_questions` | Full questionnaire graph and metadata (service-defined structure) |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Missing `model_id` | 400 | `model_id is mandatory` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required parameter (`model_id`) |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: model_id
          in: query
          required: true
          description: |
            **Required.** Walk template/model ID used to load questionnaire metadata and section/question
            definitions. Obtained from `GET /walk/v1/walks/types`.
          schema:
            type: string

        - name: form_trace_id
          in: query
          required: false
          description: |
            Existing walk instance trace ID. When provided, questionnaire answers are pre-populated
            from the in-progress walk. Used for resume, review, and reopen scenarios. When omitted,
            an empty questionnaire definition is returned.
          schema:
            type: string

      responses:
        '200':
          description: |
            Success — returns **`walk_questions`** questionnaire payload.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Questionnaire loaded
                  value:
                    status: OK
                    walk_questions:
                      response: []
                missingModel:
                  summary: Missing model_id (HTTP 400)
                  description: Returned as HTTP 400 (structured error body), not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              example:
                status: ER
                errorCode: E110
                response: "model_id is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Stores (/walk/v1/walks/stores)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/stores:
    get:
      tags: [WalkStores]
      summary: Distribution store list for walk scheduling
      operationId: getWalkStores
      description: |
        Returns the list of eligible distribution stores for scheduling a walk with the given
        model and action type. Used to populate the store-assignment picker in the schedule UI.

        Both `model_id` and `action_type` are **required**.

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_stores`** next to **`status`**.

        Distribution data usually includes **`distribution_list`** (Java `distributionList`) after
        `appendTimeZoneDates` — each entry can include store/unit fields and **`time_zone_date`**.

        ```json
        {
          "walk_stores": {
            "distribution_list": []
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_stores` | Store distribution payload from `getDistribution` (normalized keys) |

        ---

        ## Action Types

        | Value | Description |
        |---|---|
        | `A` | Adhoc — eligible stores for an adhoc walk |
        | `S` | Schedule — eligible stores for a scheduled walk |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Missing or invalid `action_type` | 400 | `action_type is mandatory or invalid` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required parameter (`model_id` or `action_type`) |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: model_id
          in: query
          required: true
          description: |
            **Required.** Walk template/model ID used to compute eligible distribution stores.
            Obtained from `GET /walk/v1/walks/types`.
          schema:
            type: string

        - name: action_type
          in: query
          required: true
          description: |
            **Required.** Determines the distribution scope:
            - `A` — Adhoc walk store list
            - `S` — Scheduled walk store list
          schema:
            type: string
            enum: [A, S]

      responses:
        '200':
          description: |
            Success — returns **`walk_stores`** (e.g. with `distribution_list`).
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Store distribution list
                  value:
                    status: OK
                    walk_stores:
                      distribution_list: []
                missingActionType:
                  summary: Missing action_type (HTTP 400)
                  description: Returned as HTTP 400 (structured error body), not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "action_type is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              examples:
                missingModelId:
                  summary: model_id missing
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
                missingActionType:
                  summary: action_type missing
                  value:
                    status: ER
                    errorCode: E110
                    response: "action_type is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Permissions (/walk/v1/walks/permissions)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/permissions:
    get:
      tags: [WalkPermissions]
      summary: Walk permissions for an entity
      operationId: getWalkPermissions
      description: |
        Returns walk permission data for the specified entity. Used to determine what actions
        (conduct, schedule, view) the entity/user can perform on walks.

        `entity_id` is **required**. `permit_type` is optional (default `C`).

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_permissions`** next to **`status`**.

        ```json
        {
          "walk_permissions": { },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_permissions` | Permission data from `getWalkPermitData` (structure varies) |

        ---

        ## Permit Types

        | Value | Description |
        |---|---|
        | `C` | Conduct — can the entity conduct walks? (default) |
        | `S` | Schedule — can the entity schedule walks? |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Missing `entity_id` parameter | 400 | `entity_id is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required parameter (`entity_id`) |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: entity_id
          in: query
          required: true
          description: |
            **Required.** Entity identifier (typically the profile or user ID) for which walk
            permissions are evaluated. Missing this parameter → HTTP 400.
          schema:
            type: string
            example: "2"

        - name: permit_type
          in: query
          required: false
          description: |
            **Default:** `C`

            Type of permission to evaluate:
            - `C` — Conduct permission
            - `S` — Schedule permission
          schema:
            type: string
            default: "C"
            enum: [C, S]

      responses:
        '200':
          description: |
            Success — returns **`walk_permissions`** object.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Permissions retrieved
                  value:
                    status: OK
                    walk_permissions: {}
                missingEntityId:
                  summary: Missing entity_id (HTTP 400)
                  description: Returned as HTTP 400 (structured error body), not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "entity_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              example:
                status: ER
                errorCode: E110
                response: "entity_id is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Users (/walk/v1/walks/users)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/users:
    get:
      tags: [WalkUsers]
      summary: User list for walk assignment (scoped by profile, unit, department, org level)
      operationId: getWalkUsers
      description: |
        Returns a list of users eligible for walk assignment. All four scope parameters
        (`requested_profile_id`, `requested_unit_id`, `requested_dept_id`, `requested_level`)
        are **required**.

        **Authentication:** `X-reflexis-csrf-token-X` required. The calling user's session
        context provides additional authorization scoping.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_users`** is a **JSON array** of user records.

        ```json
        {
          "walk_users": [],
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_users` | User list from directory lookup, normalized to snake_case per element |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Missing `requested_profile_id` | 400 | `requested_profile_id is mandatory` |
        | Missing any other required parameter | 400 | `<param> is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required parameter (`requested_profile_id`, `requested_unit_id`, `requested_dept_id`, or `requested_level`) |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - name: requested_profile_id
          in: query
          required: true
          description: |
            **Required.** Target profile ID used to scope user lookup. Defines which profile
            type of users to retrieve for the assignment.
          schema:
            type: string
            example: "2"

        - name: requested_unit_id
          in: query
          required: true
          description: |
            **Required.** Target unit/store ID used to scope user lookup. Only users belonging
            to this unit are returned.
          schema:
            type: string
            example: "1001"

        - name: requested_dept_id
          in: query
          required: true
          description: |
            **Required.** Target department ID used to scope user lookup. Combined with
            `requested_unit_id` to narrow the user list to the correct department.
          schema:
            type: string
            example: "10"

        - name: requested_level
          in: query
          required: true
          description: |
            **Required.** Requested org hierarchy level used by the user-list lookup query.
            Determines the organizational depth from which users are retrieved.
          schema:
            type: string
            example: "2"

      responses:
        '200':
          description: |
            Success — returns **`walk_users`** array.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: User list for assignment
                  value:
                    status: OK
                    walk_users: []
                missingProfile:
                  summary: Missing requested_profile_id (HTTP 400)
                  description: Returned as HTTP 400 (structured error body), not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "requested_profile_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              example:
                status: ER
                errorCode: E110
                response: "requested_profile_id is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Schedule (/walk/v1/walks/schedule)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/schedule:
    post:
      tags: [WalkSchedule]
      summary: Schedule a walk for distribution to stores (multipart/form-data)
      operationId: createScheduledWalk
      description: |
        Schedules a walk and distributes it to the specified stores. The request **must** be
        sent as `multipart/form-data`.

        The eleven required fields must be present. Missing any required field returns HTTP 400
        with a validation error message listing missing fields.

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Request Headers

        | Header | Required | Description |
        |---|---|---|
        | `X-reflexis-csrf-token-X` | Yes | Session authentication token |
        | `Content-Type` | Yes | Must be `multipart/form-data` |

        ---

        ## Response Structure

        Success envelope: `{ "status": "OK", "response": <object> }` (no `message`).

        Schedule processing returns service-specific keys (often includes **`walk_list`** or status
        fields); all normalized to **snake_case**.

        ```json
        {
          "response": {
            "walk_list": []
          },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `response` | JSON object from schedule processing |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Missing required field | 400 | `<field_name> is mandatory` — each field is checked individually; first failure returns HTTP 400 with `errorCode: E110` |
        | Invalid store/instance access (non-empty `assign_store_list`) | 200 | HTTP 200 + `status: "ER"` and localized message (business error envelope) |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required multipart field (schedule-walk operation) |
        | `E108` | 500 | Walk name is mandatory |
        | `E109` | 500 | Walk description is mandatory |
        | `E301` | 500 | Walk name exceeds max length |
        | `E302` | 500 | Walk description exceeds max length |
        | `E500` | 500 | Unhandled server error |

      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              description: Walk schedule form data. All required properties must be present.
              properties:
                model_id:
                  type: string
                  description: "**Required.** Walk template/model identifier."
                category_id:
                  type: string
                  description: "**Required.** Category identifier."
                start_date:
                  type: string
                  description: |
                    **Required.** Walk start date. **Format:** `YYYY-MM-DD`.
                  example: "2026-04-13"
                end_date:
                  type: string
                  description: |
                    **Required.** Walk end date. **Format:** `YYYY-MM-DD`.
                  example: "2026-04-13"
                start_time:
                  type: string
                  description: |
                    **Required.** Walk start time. **Format:** `h:mm AM/PM`.
                  example: "12:00 AM"
                walk_name:
                  type: string
                  description: "**Required.** Display name for the scheduled walk. Length-limited."
                  example: "Regional Compliance Q2"
                walk_description:
                  type: string
                  description: "**Required.** Walk description. Length-limited."
                  example: "Q2 regional compliance inspection"
                created_by:
                  type: string
                  description: "**Required.** Creator user identifier (login ID)."
                  example: "SYSADMIN"
                creator_unit:
                  type: string
                  description: "**Required.** Creator's unit/store identifier."
                  example: "1001"
                cluster_child_id:
                  type: string
                  description: |
                    **Required.** Cluster child identifier. Use `"-1"` when not applicable to
                    a specific cluster child.
                  example: "-1"
                assign_store_list:
                  type: string
                  description: |
                    **Required.** Comma-separated list of store/unit IDs to assign the scheduled
                    walk to. Obtained from `GET /walk/v1/walks/stores`.
                  example: "Store1,Store2"
                image_key:
                  type: string
                  description: Optional image key for the walk's cover image.
                announced_visit:
                  type: string
                  description: |
                    Optional announced visit flag (`Y`/`N`). Indicates whether the visit is
                    announced to the assigned stores.
                  enum: ["Y", "N"]
                visit_profile_map:
                  type: string
                  description: |
                    Optional visit profile mapping. JSON-encoded object mapping visit profiles.
                    Pass `"{}"` when no profile mapping is required.
                  example: "{}"
                walk_participants:
                  type: string
                  description: Optional walk participants list. Comma-separated user identifiers.
                time_zone_long:
                  type: string
                  description: |
                    Optional IANA time zone ID for the scheduled walk.
                  example: "US/Central"
                reference_key:
                  type: string
                  description: Optional reference key for external system correlation.
                time_zone_off_set:
                  type: string
                  description: |
                    Optional time zone offset in minutes from UTC. Negative for west of UTC.
                  example: "-330"
                max_org_lvl:
                  type: string
                  description: Optional maximum org level for distribution scope calculation.
                schedule_category:
                  type: string
                  description: |
                    Optional schedule category code:
                    - `S` — Standard scheduled walk
                  example: "S"
                offline_flag:
                  type: string
                  description: |
                    Optional offline distribution flag:
                    - `Y` — distribute as offline-enabled
                    - `N` — standard online distribution (default)
                  enum: ["Y", "N"]
                  example: "N"
                future_flag:
                  type: string
                  description: |
                    Optional future walk flag:
                    - `Y` — create as a future scheduled walk
                    - `N` — create as immediately active
                  enum: ["Y", "N"]
                  example: "Y"
                form_trace_id:
                  type: string
                  description: Optional form trace identifier; used for rescheduling an existing walk.

              required:
                - model_id
                - category_id
                - walk_name
                - walk_description
                - start_date
                - start_time
                - end_date
                - created_by
                - creator_unit
                - cluster_child_id
                - assign_store_list

      responses:
        '200':
          description: |
            Walk scheduled. Returns **`response`** from schedule processing.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk scheduled successfully
                  value:
                    status: OK
                    response:
                      walk_list: []
                validationError:
                  summary: First missing required field (HTTP 400)
                  description: Returned as HTTP 400 (structured error body), not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              example:
                status: ER
                errorCode: E110
                response: "model_id is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Submit (/walk/v1/walks/submit)
  # ---------------------------------------------------------------------------
  /walk/v1/walks/submit:
    post:
      tags: [WalkSubmit]
      summary: Submit questionnaire answers for a walk instance (multipart/form-data)
      operationId: submitWalkQuestionnaire
      description: |
        Submits the questionnaire answers for an in-progress walk instance. The request
        **must** be sent as `multipart/form-data`.

        All four required fields must be present. Missing any required field returns HTTP 400.

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Request Headers

        | Header | Required | Description |
        |---|---|---|
        | `X-reflexis-csrf-token-X` | Yes | Session authentication token |
        | `Content-Type` | Yes | Must be `multipart/form-data` |

        ---

        ## Response Structure

        Success envelope: `{ "status": "OK", "response": <object> }` from questionnaire submission
        (no `message`). Inner fields vary (completion status, scoring, etc.) and are **snake_case** in JSON.

        ```json
        {
          "response": { },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `response` | Normalized submission result from questionnaire upload processing |

        ---

        ## Answers Format

        The `answers` field must be a **stringified JSON array** of answer objects:
        ```json
        [
          { "question_id": "Q1", "answer": "Yes" },
          { "question_id": "Q2", "answer": "3" }
        ]
        ```

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Missing required field | 400 | `<field_name> is mandatory` — each mandatory param is checked individually; first failure returns HTTP 400 (`errorCode: E110`) |
        | Questionnaire validation failed | 200 | HTTP 200 `status: "ER"`, `error` is a **JSON array** of localized validation messages (questionnaire validation) |
        | Internal server error | 500 | `Error while processing request. Here is the error : <error details>` |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing required multipart field (submit-questionnaire operation) |
        | `E500` | 500 | Unhandled server error |
        | — | 200 | Validation failures after mandatory checks: `status: "ER"`, `error` only (no `errorCode`) |

      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              description: Walk submission form data. All required fields must be present.
              properties:
                model_id:
                  type: string
                  description: "**Required.** Walk template/model identifier."
                category_id:
                  type: string
                  description: "**Required.** Category identifier associated with the model."
                form_trace_id:
                  type: string
                  description: |
                    **Required.** Walk instance trace ID identifying the in-progress walk to submit.
                    Obtained from `GET /walk/v1/walks/` or the create walk response.
                answers:
                  type: string
                  description: |
                    **Required.** Stringified JSON array of questionnaire answers. Each element
                    must contain at minimum `question_id` and `answer`.

                    Example:
                    ```json
                    [{"question_id":"Q1","answer":"Yes"},{"question_id":"Q2","answer":"3"}]
                    ```
                  example: '[{"question_id":"Q1","answer":"Yes"}]'
              required:
                - model_id
                - category_id
                - form_trace_id
                - answers

      responses:
        '200':
          description: |
            Walk submitted. Returns **`response`** from questionnaire submission (completion metadata).
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk submitted successfully
                  value:
                    status: OK
                    response: {}
                questValidation:
                  summary: Questionnaire validation errors (HTTP 200)
                  description: |
                    HTTP 200 body. Validation produces a list of localized error messages surfaced under `error`
                    as a **JSON array**.
                  value:
                    status: ER
                    error:
                      - "Answer for question Q1 is required."
                      - "Attachment is required for question Q3."
                missingField:
                  summary: Missing mandatory field (HTTP 400 — required-parameter validation)
                  description: Returned as HTTP 400, not HTTP 200.
                  value:
                    status: ER
                    errorCode: E110
                    response: "model_id is mandatory"
        '400':
          description: Invalid or missing required request parameter.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiErrorResponse'
              example:
                status: ER
                errorCode: E110
                response: "model_id is mandatory"
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'

  # ---------------------------------------------------------------------------
  # Walk Detail (/walk/v1/walks/{walk-id})
  # ---------------------------------------------------------------------------
  /walk/v1/walks/{walk-id}:
    get:
      tags: [WalkDetail]
      summary: Get walk detail by walk-id (form_unique_id)
      operationId: getWalkById
      description: |
        Returns full detail for a specific walk instance identified by its `form_unique_id`
        (the `walk-id` path parameter). Supports additional filtering via query parameters
        for view scope and schedule type.

        **Path parameter:** `walk-id` is the `form_unique_id` returned in the walk list
        (`GET /walk/v1/walks/` or `GET /walk/v1/walks/scheduled`).

        **Authentication:** `X-reflexis-csrf-token-X` required.

        ---

        ## Response Structure

        Success envelope: top-level **`walk_details`** next to **`status`**
        (no `message`, no `response` wrapper).

        ```json
        {
          "walk_details": { },
          "status": "OK"
        }
        ```

        | Field | Description |
        |---|---|
        | `walk_details` | Detail payload from walk resolution (normalized keys) |

        ---

        ## View Types

        | Value | Description |
        |---|---|
        | `M` | My Walk — own walk detail (default) |
        | `A` | All Walk — any walk detail in the domain |
        | `R` | Walk To Reopen — detail for reopen eligibility |

        ---

        ## Schedule Types

        | Value | Description |
        |---|---|
        | `A` | Adhoc (default) |
        | `R` | Repeating |
        | `S` | Scheduled |

        ---

        ## Error Scenarios

        | Scenario | HTTP Status | Message |
        |---|---|---|
        | Missing `X-reflexis-csrf-token-X` header | 400 | `X-reflexis-csrf-token-X header is mandatory` |
        | Invalid or expired token | 401 | `Invalid or expired token` |
        | Blank `walk-id` path parameter | 400 | `<walk-id> is mandatory` |
        | Walk not found or business error from services | 200 | HTTP 200 + `status: "ER"` and `error` message from service layer |
        | Internal server error | 500 | `Unexpected server error.` or structured error body (`errorCode` + `response`) |

        ## Error Codes Reference

        | Code | HTTP | Description |
        |---|---|---|
        | `E112` | 400 | `X-reflexis-csrf-token-X` header is mandatory |
        | `E101` | 400 | Domain id is mandatory (session payload) |
        | `E202` | 401 | User session is invalid (MyWork) |
        | `E204` | 401 | Invalid or expired token |
        | `E110` | 400 | Missing/blank `walk-id` path parameter |
        | `E500` | 500 | Unhandled server error |

      parameters:
        - $ref: '#/components/parameters/WalkId'

        - name: view_type
          in: query
          required: false
          description: |
            View scope while resolving walk detail:
            - `M` — My Walk (default; own walk context)
            - `A` — All Walk (any walk in domain)
            - `R` — Walk To Reopen (reopen eligibility context)
          schema:
            type: string
            enum: [A, M, R]

        - name: schedule_type
          in: query
          required: false
          description: |
            Schedule type filter for resolving related walk context:
            - `A` — Adhoc
            - `R` — Repeating
            - `S` — Scheduled
          schema:
            type: string
            enum: [A, R, S]

      responses:
        '200':
          description: |
            Success — returns **`walk_details`** object.
            Application-level errors are returned as HTTP 200 with `status: "ER"`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalkApiSuccessResponse'
              examples:
                success:
                  summary: Walk detail response
                  value:
                    status: OK
                    walk_details: {}
                notFound:
                  summary: Walk not found (application-level)
                  value:
                    status: ER
                    error: "Walk not found for the given walk-id"
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
