{"templateId":"markdown","sharedDataIds":{},"props":{"metadata":{"markdoc":{"tagList":[]},"type":"markdown"},"seo":{"title":"B2B v2 Production Contract Remediation Plan","description":"Official Altegio API documentation for integrating online booking, CRM, scheduling, POS, and business management features into your applications.","siteUrl":"https://developer.alteg.io","lang":"en","keywords":["Altegio API","REST API","online booking API","appointment scheduling API","business management API","CRM integration","POS API"],"image":"/assets/og-image.5c9c342f49e4dd72b96f7a0faf29bb71fab6ff06bbf97cf4b230d6fcc0abcdb3.e746d8a7.jpg","meta":[{"name":"author","content":"Altegio"},{"name":"twitter:card","content":"summary_large_image"},{"name":"twitter:site","content":"@altegio"}],"llmstxt":{"hide":false,"sections":[{"title":"Table of contents","includeFiles":["**/*"],"excludeFiles":[]}],"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"b2b-v2-production-contract-remediation-plan","__idx":0},"children":["B2B v2 Production Contract Remediation Plan"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Status:"]}," Ready for implementation"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Audit snapshot:"]}," 2026-07-15"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Scope:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.alteg.io/api/v2"]}," only"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Primary specification:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/b2b-v2/openapi.yaml"]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"outcome","__idx":1},"children":["Outcome"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Make the B2B v2 documentation describe the production API exactly, then make the"," ","production checks fail when that contract drifts."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The current v2 specification contains 22 paths and 31 operations. Production"," ","routes exist for all of them, but much of the documentation was written before"," ","the corresponding API implementation existed. The result is a mixture of real"," ","contracts and old mock contracts."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["This plan is split into small, independent sessions so a new session can safely"," ","take one section, verify it against production, open a focused pull request, and"," ","stop without depending on chat history."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"non-negotiable-scope-rules","__idx":2},"children":["Non-negotiable scope rules"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Audit and edit B2B v2 only."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["V1 may be called only to authenticate a Business User and discover a test"," ","Location. Do not change or assess the V1 contract in these sessions."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every v2 request must send:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"http","header":{"controls":{"copy":{}}},"source":"Accept: application/vnd.api.v2+json\nAuthorization: Bearer <partner_token>, User <user_token>\n","lang":"http"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The required ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Accept"]}," header does not select between two successful response"," ","formats. Production returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}," without the v2 media type and returns the"," ","JSON:API-style representation when the header is valid."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use production behavior as the source of truth. Old examples, old mocks, and"," ","endpoint names are not evidence."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Preserve wire names exactly, even when they use legacy terminology."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the documentation vocabulary in prose: Location, Team Member, Appointment,"," ","Booking User, and Business User."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not retain legacy terminology in prose merely because a canonical term or"," ","route is not implemented in v2 yet. Show a legacy name only as a"," ","code-formatted wire literal, then describe it with the approved vocabulary."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not refactor unrelated V1 paths, shared schemas, formatting, or navigation."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Do not commit credentials, tokens, customer data, raw production responses,"," ","or identifiable test data."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"starting-a-new-implementation-session","__idx":3},"children":["Starting a new implementation session"]},{"$$mdtype":"Tag","name":"ol","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Read this entire plan and the repository ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AGENTS.md"]},"."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Inspect the current state before editing:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"git status --short --branch\ngit fetch origin\ngit log --oneline --decorate -10\n","lang":"bash"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Preserve any existing working-tree changes. Do not overwrite another"," ","session's edits."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Create a new branch directly from the latest remote default branch:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"git switch -c docs/v2-<session-scope> origin/master\n","lang":"bash"},"children":[]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Read every target path file before changing it. Search for shared schemas and"," ","callers before creating new files."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Re-run the relevant live probes. The observations below are a dated snapshot,"," ","not permission to skip current verification."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Change only the endpoint group assigned to the session."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Run the required validation, commit, push, and open a focused PR."]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"verified-production-baseline","__idx":4},"children":["Verified production baseline"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"authentication-and-media-type","__idx":5},"children":["Authentication and media type"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The following behavior was verified on Services, Appointments, and Positions:"]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Request Accept value"},"children":["Request ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Accept"]}," value"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Production result"},"children":["Production result"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["application/vnd.api.v2+json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Successful JSON:API-style response"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Omitted"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["*/*"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["application/json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["application/vnd.api.v1+json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The production error message explicitly requires"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Accept: application/vnd.api.v2+json"]},". A charset parameter is accepted."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"response-vocabulary","__idx":6},"children":["Response vocabulary"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The public URL vocabulary is new, while several wire-level JSON:API resource"," ","types remain legacy values. Documentation must explain this mapping instead of"," ","inventing new wire values."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Public documentation term"},"children":["Public documentation term"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Production path term"},"children":["Production path term"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Production type"},"children":["Production ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type"]}]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Service"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["services"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["service"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Product"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["products"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Product Category"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["product_categories"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good_category"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Product Storage Amount"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage_amounts"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good_storage_amount"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Team Member"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["team_members"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["staff"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Appointment"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["appointments"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["record"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Event"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["events"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["activity"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Position"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["positions"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Tag"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tags"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tag"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["IDs in successful resource objects are strings, as expected for JSON:API-style"," ","resource identifiers. Do not document them as integers inside the response"," ","resource object merely because the path parameter is an integer."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"common-success-and-error-shapes","__idx":7},"children":["Common success and error shapes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Successful collection responses use resource objects:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"data\": [\n    {\n      \"type\": \"service\",\n      \"id\": \"123\",\n      \"attributes\": {}\n    }\n  ]\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Some collections also return pagination metadata. Detail responses commonly add"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"meta\": []"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Production errors consistently use:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"json","header":{"controls":{"copy":{}}},"source":"{\n  \"success\": false,\n  \"data\": null,\n  \"meta\": {\n    \"message\": \"...\",\n    \"errors\": {}\n  }\n}\n","lang":"json"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta.errors"]}," is present only for field-level validation errors."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"live-coverage-completed-in-the-audit","__idx":8},"children":["Live coverage completed in the audit"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Positive authenticated GET responses were captured for 17 of 18 GET"," ","operations."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The positive Attendance Product Item response was not captured because the"," ","test Location had no safe fixture. Its route and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," behavior were verified."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Full temporary CRUD was completed for Tags, Positions, and Events."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event Appointment create/update routes were verified through validation"," ","responses only to avoid creating or notifying a Booking User."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Appointment delete and timetable delete were verified using nonexistent IDs;"," ","no existing Appointment was modified."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every temporary Tag, Position, and Event was cleaned up after testing."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"known-contract-gaps-by-area","__idx":9},"children":["Known contract gaps by area"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"services","__idx":10},"children":["Services"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/services/v2/location.services.list.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/services/v2/location.services.read.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/services/v2/location.service_categories.list.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/services/v2/service_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/services/v2/service_category_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/services/v2/error_response.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All success responses are JSON:API-style resources with string IDs."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Service attributes observed: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["category_id"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Service Category attributes observed: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["salon_service_id"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["filter[service_ids][]"]}," work for the Service list."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Production uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]},"; the previously documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," parameter is"," ","ignored."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No pagination ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]}," was returned by the Service list."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The previously documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["category"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["staff"]}," include values have no"," ","effect. Production supports ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["resources"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["service_composite"]},","," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["resource_links"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["company_links"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["trial_settings"]},"; effective includes"," ","add JSON:API relationships and may add top-level ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["included"]}," resources."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Service Categories use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["filter[staff_id]"]},". Revalidation with a nonexistent"," ","Team Member ID changed the collection, and current PHP passes the filter to"," ","the category provider."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"products","__idx":11},"children":["Products"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.products.list.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.products.autocomplete.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.products.read.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.products.storage_amounts.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.product_categories.list.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.product_categories.read.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/products/v2/location.attendance_product_items.read.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/product_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/product_category_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/storage_amount_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/attendance_product_item_resource.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/json_api.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/products/v2/error_response.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product resources use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: good"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product Category resources use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: good_category"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Storage Amount resources use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: good_storage_amount"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product attributes differ materially from the current flat mock. Observed"," ","fields include ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["actual_cost"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["cost"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["category_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["consumable_unit_id"]},","," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sale_unit_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sale_unit_to_consumable_unit_ratio"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["is_chain"]},", and loyalty"," ","entity IDs."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Storage Amount attributes observed: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage_id"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sale_amount"]},","," ","and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["consumable_amount"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product Category attributes observed: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["is_chain"]},", and"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["parent_category_id"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["List and autocomplete pagination is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," based. Production returns"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta.pagination.page"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The previously documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," query parameter on Product list is"," ","ignored. Production uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product ID filtering works."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The previously documented Product and Product Category include values have"," ","no effect. Revalidation confirmed the PHP include keys for Products,"," ","Product Categories, Storage Amounts, and Appointment Product Items."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage_amounts"]}," works for Product detail but returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["422"]}," for Product list"," ","and autocomplete. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["actual_cost"]}," works for Product list and detail only when"," ","the Business User has permission; autocomplete leaves it ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The Appointment Product Item positive shape is verified from the current PHP"," ","transformer. Its route and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," response are live-verified, but the test"," ","Location still has no safe positive fixture."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"team-members","__idx":12},"children":["Team Members"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target file:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/team_members/v2/location.team_members.list.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Resources use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: staff"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Observed attributes: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["name"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["specialization"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["image"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position_id"]},","," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["is_available_as_assistant"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tt_markup"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Name, Position, and tri-state filters work."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Invalid tri-state values return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["422"]}," with field errors."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Current PHP exposes the literal include keys ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["employee"]},"."," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position"]}," uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: staff_position"]},"; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["employee"]}," uses ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: employee"]}," and"," ","returns the employment profile fields defined by the transformer."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The previously documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["services"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schedule"]}," include values are not"," ","supported by the current transformer."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Production revalidation currently returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Insufficient rights"]}," for"," ","every Location returned to the test Business User. The controller gates the"," ","operation through ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["hasSalonAccess"]},". Positive resource and include shapes are"," ","therefore verified from the current controller, filter DTO, and transformers"," ","rather than a fresh positive fixture."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"appointments","__idx":13},"children":["Appointments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/appointments/v2/location.appointments.list.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/appointments/v2/location.appointments.delete.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/appointments/v2/location.appointments.bulk_delete.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Appointment resources use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: record"]}," and contain substantially more"," ","attributes than the current mock schema."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Pagination is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," based. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," is ignored; undocumented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," works."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Date filters require ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["YYYY-MM-DDTHH:MM:SS"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The current transformer exposes Booking User, Team Member, Service, Product,"," ","resource, label, attendance, payment, Custom Field Value, visitor,"," ","notification, schedule, and duration relationships through literal include"," ","keys. The deprecated Team Member include alias is intentionally omitted."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/timetable/appointments/delete"]}," is not a bulk array endpoint in production."," ","It requires one numeric ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recordId"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Sending the documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["appointment_ids"]}," returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["422"]}," and reports that"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recordId"]}," is missing."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A nonexistent numeric ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recordId"]}," reaches the handler and returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The timetable-delete controller returns the remaining Appointments related to"," ","the deleted Appointment as a JSON:API collection. An Appointment without"," ","related records therefore returns an empty ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["data"]}," array."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Current production revalidation returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Insufficient rights"]}," for the"," ","Appointment list because the test Business User no longer has timetable"," ","access to any returned Location. No temporary Appointment was created or"," ","modified. Positive list and delete shapes are verified from the current"," ","controller, DTOs, transformer, and deletion service."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"positions","__idx":14},"children":["Positions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/positions/v2/company.positions.list.create.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/positions/v2/company.positions.read.update.delete.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Collection, detail, and create responses use JSON:API-style Position"," ","resources."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["services_binding_type"]}," is numeric in production. The current Position"," ","interface defines ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["0"]}," (disabled), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["1"]}," (soft), and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["2"]}," (strict)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["List responses omit ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]},"; detail and create responses return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]}," as an"," ","array."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," on the list appeared to be ignored."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create succeeds with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]},"; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["description"]}," is accepted."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Production rejects the documented create ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["salon_ids"]}," as unexpected."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Update succeeds with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["title"]}," and optional ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["description"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Production rejects the documented update ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position_id"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["salon_ids"]}," as"," ","unexpected."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Create returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["201"]},"; update and delete return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["204"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The pre-existing partial Position corrections were inspected and preserved."," ","The numeric enum is now supported by current implementation evidence."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Current revalidation returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Insufficient rights"]}," for every Location"," ","returned to the test Business User. No temporary Position was created or"," ","modified. The response and write contracts retain the earlier live audit"," ","evidence, with the binding enum additionally verified from the current PHP"," ","interface."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Position resource schema uses a unique component filename. Reusing"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["position_resource.yml"]}," conflicted with the Team Member include schema during"," ","Redocly bundling and caused the Cloud Project build to fail."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"tags","__idx":15},"children":["Tags"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/tags/v2/company.tags.list.create.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/tags/v2/company.tags.read.update.delete.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/schemas/tags/v2/tag_attributes.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["CRUD bodies, response resource fields, and status codes largely match the"," ","current documentation."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The list response omits the documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Alias and numeric entity filters return equivalent results."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Invalid entity values return ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["400"]}," with a useful message."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Treat this session as validation and tightening, not a rewrite."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Current revalidation returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Insufficient rights"]}," for every Location"," ","returned to the test Business User. No temporary Tag was created or modified."," ","The list envelope, entity filters, validation behavior, and CRUD status codes"," ","retain the earlier live audit evidence."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"events-and-event-appointments","__idx":16},"children":["Events and Event Appointments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Target files:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/b2b-v2/openapi.yaml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/events/v2/location.events.list.create.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/events/v2/location.events.read.update.delete.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/events/v2/location.events.records.create.yml"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/en/paths/events/v2/location.events.records.update.yml"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Known production behavior:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The canonical new route works for list, create, read, update, and delete:"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/locations/{location_id}/events"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The alias ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/locations/{location_id}/activities"]}," also works."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The alias ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/companies/{location_id}/activities"]}," also works."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The specification now publishes only the canonical route; working aliases are"," ","intentionally omitted from the primary reference."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event list responses use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["type: activity"]},", string IDs, and attributes."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event create, read, and update JSON:API-style schemas are close to production."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event create returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["201"]},", update returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]},", and delete returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["204"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["After delete, the Event disappears from list results, but direct read still"," ","returned ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]}," in the audit. Revalidate and document soft-delete semantics if"," ","stable."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event filters require ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["YYYY-MM-DD HH:MM:SS"]}," with a space. RFC 3339 values with"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["T"]}," are rejected; the request schemas now use the production pattern."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event Appointment create, update, and reschedule routes and required-field"," ","validation exist, but positive writes still need a controlled Booking User"," ","fixture and notification safety review."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Current revalidation on 2026-07-16 returns ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403 Insufficient rights"]}," for the"," ","canonical Event route at all 25 Locations available to the test Business User;"," ","both working aliases return the same result for the representative Location."," ","No Event or Event Appointment was created or modified."," ","The sibling PHP implementation confirms the canonical alias mapping, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," and"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," pagination, the exact Event resource transformer, and soft deletion:"," ","deleted Events leave list results while direct retrieval does not reject the"," ","deleted state. It also confirms separate ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUT"]}," update and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PATCH"]}," reschedule"," ","operations for Event Appointments. Positive Event Appointment coverage remains"," ","blocked by the missing writable Location and controlled notification-safe"," ","Booking User fixture; the PHP integration suite is the current positive-write"," ","evidence."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"implementation-sessions","__idx":17},"children":["Implementation sessions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Each session should result in one focused PR. Do not combine sessions unless the"," ","files and validation are genuinely inseparable."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-1-contract-primitives-and-guardrails","__idx":18},"children":["Session 1: Contract primitives and guardrails"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: establish reusable, production-shaped components without changing endpoint"," ","semantics."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Inventory existing v2 schemas and response files."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add or reuse small shared components for JSON:API resource identifiers,"," ","pagination metadata, and the standard error envelope only when reuse reduces"," ","duplication across at least three endpoint groups."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Document the required v2 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Accept"]}," header once in the top-level description and"," ","keep operation-level required headers consistent."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Do not introduce a broad schema architecture refactor."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Components validate under OpenAPI 3.1."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No endpoint behavior is invented."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Existing references still resolve."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["npm test"]}," introduces no new warnings."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-2-services","__idx":19},"children":["Session 2: Services"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: replace all three mock success schemas and examples with verified"," ","JSON:API-style contracts."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct list, detail, and Service Category resource shapes."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct string ID types and actual attributes."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," with the effective ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," parameter and correct the default"," ","and maximum ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["limit"]}," values."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove pagination metadata that production does not return."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace ineffective include values with the verified Service include keys."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct the Team Member filter to the literal ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["filter[staff_id]"]}," wire name."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace flat error schemas with the production error envelope."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add missing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," responses."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Live list/detail/category responses validate against the edited schemas."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Limit, page, ID filtering, Team Member filtering, and Service includes are"," ","tested."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No Service example contains fields absent from the live response."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-3-products","__idx":20},"children":["Session 3: Products"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: correct all seven Product-area operations."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Model ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good_category"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["good_storage_amount"]}," resources."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct attribute names and types."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]}," where production proves page-based pagination."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct pagination metadata."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace ineffective include values with the operation-specific PHP keys that"," ","current production revalidation proves effective."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Obtain a safe Appointment Product Item fixture or explicitly mark its positive"," ","schema as unverified rather than fabricating it."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct standard errors and add missing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," responses."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product list, autocomplete, detail, category list/detail, and storage amounts"," ","validate against live responses."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Page 1 and page 2 return different first resources in the test fixture."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Product ID filtering is verified."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Appointment Product Item confidence is stated explicitly."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-4-team-members","__idx":21},"children":["Session 4: Team Members"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: replace the old flat Team Member response with the live ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["staff"]}," resource."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct attributes, string IDs, filters, and errors."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove ineffective include claims unless current behavior has changed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add the missing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," response."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Base list and representative filters validate live."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Invalid tri-state values validate against the documented ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["422"]}," envelope."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-5-appointments","__idx":22},"children":["Session 5: Appointments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: correct Appointment resources, pagination, and timetable deletion."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Model the live ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["record"]}," resource and its verified attributes."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Document ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["page"]},", not the ignored ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["offset"]}," behavior."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct date formats and examples."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove ineffective includes unless revalidated."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace the false bulk ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["appointment_ids[]"]}," contract with the production"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["recordId"]}," request."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use a temporary Appointment fixture to verify the successful timetable-delete"," ","status and body, with cleanup in the same test flow."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct errors and missing ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," responses."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["List pages and filters validate live."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Single delete and timetable delete are verified using temporary fixtures only."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No existing Appointment is modified."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Test fixtures are absent after the run."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-6-positions","__idx":23},"children":["Session 6: Positions"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: make Position reads and writes usable from the documentation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Revalidate and document the numeric ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["services_binding_type"]}," values."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]}," presence and type."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove unsupported list pagination."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct create and update request bodies."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Update the Position section of the Arazzo workflow only after the OpenAPI"," ","contract is correct."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Temporary create, read, update, and delete all succeed from documented bodies."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The temporary Position is removed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Production responses validate without schema warnings."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-7-tags","__idx":24},"children":["Session 7: Tags"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: tighten the already mostly correct Tag documentation."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Revalidate list, filters, CRUD, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["meta"]},", and errors."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove stale “not yet deployed” language and 404 skip behavior."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Avoid unrelated Tag schema rewrites."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Full temporary CRUD succeeds and cleans up."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Alias and numeric filters are both covered."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["List and detail responses validate exactly."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-8-events-and-event-appointments","__idx":25},"children":["Session 8: Events and Event Appointments"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: publish the canonical Event API and correct the remaining mock contracts."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Register ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/locations/{location_id}/events"]}," as the canonical documented path."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Decide, based on product compatibility policy, whether working aliases should"," ","be documented as deprecated aliases or omitted from the primary reference."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Replace the flat Event list schema with the live ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["activity"]}," resource."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct the production date-time pattern and examples without falsely using"," ","RFC 3339 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["format: date-time"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Revalidate Event CRUD and soft-delete behavior."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Build a controlled fixture for Event Appointment create/update only after"," ","confirming that Booking User notifications and Booking User creation are"," ","safe."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Correct Event Appointment success schemas if the live fixture differs."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Canonical Event CRUD succeeds and cleans up."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event list/detail/create/update responses validate."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The v2-specific Redocly date warnings are eliminated."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Event Appointment positive coverage is either completed safely or explicitly"," ","documented as blocked with the exact missing fixture/safety requirement."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-9-arazzo-and-ci-hardening","__idx":26},"children":["Session 9: Arazzo and CI hardening"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: make automated checks detect future contract drift."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Expand ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/api-fast-check-b2b-v2.arazzo.yaml"]}," from Tags/Positions to safe"," ","read coverage for every v2 group."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Remove success criteria that accept ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," because an endpoint may be"," ","undeployed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Add explicit dependencies and cleanup for every created resource."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Ensure cleanup runs on failure where the runner supports it. If it does not,"," ","split destructive workflows or add a deterministic cleanup workflow."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Use unique test names to avoid collisions."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Promote ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schemaCheck"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warn"]}," to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["error"]}," only after all live schemas are"," ","corrected."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Do not make destructive checks depend on pre-existing production data."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Important audit evidence: the existing smoke workflow left an ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Arazzo Test Tag"]}," ","after an incomplete run. It was deleted manually. Cleanup is therefore a"," ","required part of this session, not an optional improvement."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implemented and production-validated on 2026-07-16:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The build workflow is read-only and covers collection responses for Services,"," ","Products, Team Members, Positions, Appointments, Events, and Tags. All seven"," ","groups require ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["200"]},"; no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," response is accepted as success."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Tag and Position mutations are isolated in a manual workflow. Each caller"," ","supplies a unique run ID, every post-create failure routes to deletion, and a"," ","failed deletion is retried twice."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The repository guard bundles both Arazzo descriptions and the v2 OpenAPI"," ","description. It rejects missing read groups, any v2 mutation in the build"," ","workflow, accepted ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["404"]}," criteria, missing cleanup routes, a registered"," ","destructive Reunite job, or a non-error v2 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["schemaCheck"]}," severity."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The read-only production workflow passed 9 of 9 steps and 36 of 36 checks."," ","The isolated Tag and Position workflows passed 12 of 12 steps and 40 of 40"," ","checks, then a separate list audit found no remaining fixtures."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A forced Tag read failure ran the failure cleanup action successfully; a"," ","follow-up list audit again found no fixture. A deliberately corrupted Service"," ","response schema failed Respect at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["listServices"]},", confirming that schema drift"," ","is build-blocking."]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The final Redocly preview status reported ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["All Respect Monitoring checks passed"]},". An earlier ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["No Respect Monitoring workflows found"]}," status appeared"," ","only while the Project preview was still building and was replaced when the"," ","configured workflows completed."]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["All safe read checks run on every build."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No “not deployed” 404 path can produce a green build."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Intentional schema corruption makes the workflow fail."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Failed CRUD testing leaves no Tag, Position, Appointment, or Event fixture."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"session-10-final-cross-group-verification","__idx":27},"children":["Session 10: Final cross-group verification"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Goal: verify the complete v2 reference as one production contract."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Work:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Recount paths and operations; expected baseline is 22 paths and 32 operations."," ","The additional operation is the production-supported Event Appointment"," ","reschedule operation documented in Session 8."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run Redocly lint for ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["en/b2b-v2/openapi.yaml"]}," and the repository baseline."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Run the completed v2 Arazzo workflow."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Manually inspect representative rendered pages for each tag."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Verify terminology in prose while preserving wire names."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Search for stale mock markers such as flat success resources, integer JSON:API"," ","IDs, “not yet deployed,” ineffective includes, and obsolete Event-only paths."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implemented and verified on 2026-07-16:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The bundled reference contains 22 paths and 32 operations: 18 GET, 5 POST,"," ","4 PUT, 1 PATCH, and 4 DELETE. Every operation documents 401, 403, and 404."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every JSON:API-style resource schema uses a string ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["id"]},". Source and bundled"," ","prose contain no superseded domain term outside an explicitly marked literal"," ","wire key, value, resource type, or URL parameter. No stale mock or deployment"," ","marker remains."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Redocly CLI 2.14.4 and 2.39.0 both lint the v2 description with no warnings."," ","The repository baseline passes with 0 errors and 507 warnings against a"," ","budget of 510."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The production read-only workflow passes 9 of 9 steps and 36 of 36 checks."," ","Services, Products, Team Members, Positions, Appointments, Events, and Tags"," ","each return 200 and validate against the published schema."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The published Services, Products, Team Members, Appointments, Events, and"," ","Tags sections were inspected in the rendered reference. The six sections,"," ","all 32 operations, and the canonical terminology render correctly."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A separate production list audit found zero Arazzo Tag, Position,"," ","Appointment, or Event fixtures."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Final evidence classification:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Documented:"]}," all 32 published operations, including their request,"," ","success, authentication, permission, and not-found contracts."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Live-verified:"]}," 17 of 18 positive GET operations from the production audit;"," ","all seven representative collection reads were revalidated in this session."," ","Tag and Position CRUD and Event CRUD also have temporary-fixture production"," ","evidence, with cleanup confirmed. Session 10 intentionally did not repeat"," ","destructive checks."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Not safely live-verified:"]}," the positive Appointment Product Item response,"," ","Appointment deletion success bodies, and positive Event Appointment writes."," ","These shapes are verified against the current PHP transformers, controllers,"," ","services, and integration tests. Repeating them in production still requires"," ","a controlled Appointment or Booking User fixture and notification-safety"," ","review."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Acceptance:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every positive live response used in the workflow validates against OpenAPI."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Every operation contains 401, 403, and 404 responses as required by repository"," ","policy, plus actual validation statuses."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The v2 spec has no v2-specific lint warnings."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The repository warning baseline does not increase."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No test fixtures remain."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The final report distinguishes documented, live-verified, and not safely"," ","verified behavior."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"required-validation-for-every-pr","__idx":28},"children":["Required validation for every PR"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Run from the repository root unless noted otherwise:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"npm test\ncd docs && ../node_modules/.bin/redocly lint en/b2b-v2/openapi.yaml\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Also run the narrow live probes for the endpoint group. Do not run all"," ","destructive workflows merely to validate a read-only schema change."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For changes to Arazzo or CRUD schemas, run:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"bash","header":{"controls":{"copy":{}}},"source":"make test-api-b2b-v2\n","lang":"bash"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After every live write test, query the relevant list endpoint and confirm that"," ","the temporary resource is gone."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"definition-of-done-for-the-remediation-program","__idx":29},"children":["Definition of done for the remediation program"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["The published v2 paths use the approved canonical terminology."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Wire-level literal values are documented accurately, not renamed."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Success and error schemas validate current production responses."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Request bodies can be copied from the documentation and used successfully."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Pagination parameters and metadata match production behavior."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Unsupported or ignored includes are not advertised as working features."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Arazzo covers every v2 group and fails on schema drift."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["404 is never treated as proof that a production v2 endpoint is healthy."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Destructive tests are isolated, uniquely named, and self-cleaning."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Redocly reports no v2-specific warnings and the repository warning budget does"," ","not increase."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Each merged PR reports live verification separately from lint success."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"handoff-template-for-a-future-session","__idx":30},"children":["Handoff template for a future session"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use this prompt with the session number filled in:"]},{"$$mdtype":"Tag","name":"blockquote","attributes":{},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Implement Session N from"," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["docs/plans/2026-07-15-b2b-v2-production-contract-remediation.md"]},"."," ","Work only on the listed B2B v2 files. Revalidate production with the required"," ","v2 Accept header, preserve wire names, avoid V1 scope, clean up every temporary"," ","resource, run the required lint/tests, and open a focused PR. Report separately"," ","what was changed, live-verified, and not safely verified."]}]}]},"headings":[{"value":"B2B v2 Production Contract Remediation Plan","id":"b2b-v2-production-contract-remediation-plan","depth":1},{"value":"Outcome","id":"outcome","depth":2},{"value":"Non-negotiable scope rules","id":"non-negotiable-scope-rules","depth":2},{"value":"Starting a new implementation session","id":"starting-a-new-implementation-session","depth":2},{"value":"Verified production baseline","id":"verified-production-baseline","depth":2},{"value":"Authentication and media type","id":"authentication-and-media-type","depth":3},{"value":"Response vocabulary","id":"response-vocabulary","depth":3},{"value":"Common success and error shapes","id":"common-success-and-error-shapes","depth":3},{"value":"Live coverage completed in the audit","id":"live-coverage-completed-in-the-audit","depth":3},{"value":"Known contract gaps by area","id":"known-contract-gaps-by-area","depth":2},{"value":"Services","id":"services","depth":3},{"value":"Products","id":"products","depth":3},{"value":"Team Members","id":"team-members","depth":3},{"value":"Appointments","id":"appointments","depth":3},{"value":"Positions","id":"positions","depth":3},{"value":"Tags","id":"tags","depth":3},{"value":"Events and Event Appointments","id":"events-and-event-appointments","depth":3},{"value":"Implementation sessions","id":"implementation-sessions","depth":2},{"value":"Session 1: Contract primitives and guardrails","id":"session-1-contract-primitives-and-guardrails","depth":3},{"value":"Session 2: Services","id":"session-2-services","depth":3},{"value":"Session 3: Products","id":"session-3-products","depth":3},{"value":"Session 4: Team Members","id":"session-4-team-members","depth":3},{"value":"Session 5: Appointments","id":"session-5-appointments","depth":3},{"value":"Session 6: Positions","id":"session-6-positions","depth":3},{"value":"Session 7: Tags","id":"session-7-tags","depth":3},{"value":"Session 8: Events and Event Appointments","id":"session-8-events-and-event-appointments","depth":3},{"value":"Session 9: Arazzo and CI hardening","id":"session-9-arazzo-and-ci-hardening","depth":3},{"value":"Session 10: Final cross-group verification","id":"session-10-final-cross-group-verification","depth":3},{"value":"Required validation for every PR","id":"required-validation-for-every-pr","depth":2},{"value":"Definition of done for the remediation program","id":"definition-of-done-for-the-remediation-program","depth":2},{"value":"Handoff template for a future session","id":"handoff-template-for-a-future-session","depth":2}],"frontmatter":{"seo":{"title":"B2B v2 Production Contract Remediation Plan"}},"lastModified":"2026-07-16T12:40:53.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/plans/2026-07-15-b2b-v2-production-contract-remediation","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}