# B2B v2 Coverage Expansion: Next Session Plan

- **Status:** Ready for implementation
- **Audit snapshot:** 2026-07-16
- **Documentation repository baseline:** `608bb35`
- **Backend repository baseline:** `22e478446e8` (`origin/master`)
- **Scope:** `https://api.alteg.io/api/v2` and `docs/en/b2b-v2/openapi.yaml`


## Outcome

Expand the published B2B v2 reference without accidentally promoting internal
backoffice routes to the public contract.

The next session must:

1. publish canonical Location URLs for Tags and Positions;
2. refresh and classify the 28-operation documentation gap;
3. publish at least the safe Waiting List read surface; and
4. publish the complete Waiting List group only when a controlled fixture makes
positive write verification safe.


Minimum success increases coverage from 32 of 60 operations to 34 of 60.
Target success increases it to 39 of 60.

## Current baseline

The backend registers 60 `/api/v2` operations in two route files:

- 53 operations in
`src/Application/Http/Routing/Routes/api/api_v2.php`;
- 7 operations in
`src/Application/Http/Routing/Routes/api/modules/waiting_list.php`.


The published B2B v2 reference contains 22 paths and 32 operations:

| Method | Backend | Published | Gap |
|  --- | --- | --- | --- |
| GET | 35 | 18 | 17 |
| POST | 10 | 5 | 5 |
| PUT | 6 | 4 | 2 |
| PATCH | 2 | 1 | 1 |
| DELETE | 7 | 4 | 3 |
| **Total** | **60** | **32** | **28** |


The 28 unpublished operations currently fall into these groups:

| Candidate group | Operations | Initial handling |
|  --- | --- | --- |
| Waiting List | 7 | First public expansion candidate |
| Attendance and related statistics | 10 | Classify before publication |
| Attendance Services | 4 | Classify before publication |
| Comer Vehicles | 4 | Treat as internal until proven otherwise |
| Units, Resource Occupations, Custom Fields | 3 | Assess as public reference data |


This is a mechanical route inventory, not proof that all 60 operations belong
in the public B2B contract.

## Contract facts already established

- Every request must send `Accept: application/vnd.api.v2+json` and combined
Partner plus Business User authorization.
- Backend routes are registered under `/locations/{locationId}`.
- `ApiUrlAliasRewriteMiddleware` maps the compatibility segment `companies` to
the canonical segment `locations`.
- Production currently resolves both Tags and Positions URL forms through the
authentication layer.
- The published spec still uses `/companies/{company_id}` for the ten Tags and
Positions operations.
- Canonical prose uses Location, Team Member, Appointment, Booking User, and
Business User.
- Literal SDK-facing parameter names such as `company_id` remain unchanged and
are described with canonical domain terminology.
- Literal wire values such as `good`, `staff`, `record`, `activity`, and
`client` must remain unchanged and be identified as wire values.


An unauthenticated `401` proves route reachability only. It does not prove that
two URLs return the same successful contract.

## Scope rules

- Work only in B2B v2 files and the related validation workflows.
- Do not document an endpoint merely because it is registered under `/api/v2`.
- Treat Vue-only consumers, backoffice-specific state, and unstable internal
handlers as evidence against public publication.
- Use production behavior as the source of truth, supported by current PHP
controllers, transformers, services, and integration tests.
- Preserve literal request keys, response keys, enum values, resource types,
and compatibility aliases.
- Do not expose credentials, personal data, or raw production payloads.
- Do not create or modify a Booking User or Waiting List entry without a
controlled fixture and an explicit cleanup path.
- Keep documented, source-verified, live-verified, and blocked evidence separate.


## Step 1: Refresh the inventory

Before editing, fetch both repositories and recount from their current default
branches. Do not assume the snapshot above is still current.

For every backend operation, record:

- HTTP method and canonical route;
- route name and controller;
- existing OpenAPI operation ID, if any;
- known application consumers;
- authentication and permission middleware;
- integration-test coverage;
- candidate classification: `public`, `internal`, or `needs decision`;
- evidence level: source-only, integration-tested, route-reachable, or positive
production response.


Save the refreshed table in this plan or a sibling dated inventory file. The
published coverage denominator must include only approved public operations;
also retain the raw 60-operation denominator for engineering visibility.

## Step 2: Canonicalize Tags and Positions

Perform authenticated read checks for both forms:

```text
/api/v2/locations/{company_id}/tags
/api/v2/companies/{company_id}/tags
/api/v2/locations/{company_id}/positions
/api/v2/companies/{company_id}/positions
```

If the canonical Location URLs return the same successful resources:

- publish only `/locations/{company_id}/tags` and
`/locations/{company_id}/positions` as primary paths;
- rename the four path files from `company.*` to `location.*`;
- preserve the literal `company_id` OpenAPI parameter name and describe it as
the Location identifier;
- keep `/companies/{company_id}` in a short compatibility note instead of
duplicating ten OpenAPI operations;
- keep operation IDs and verified wire payloads stable;
- update any Arazzo or validation reference that hard-codes the old URL.


If an authenticated canonical request fails, stop this step and record the
exact production/backend mismatch. Do not change the spec based only on the
unauthenticated route check.

## Step 3: Publish the safe Waiting List read surface

The backend exposes:

```text
GET    /locations/{location_id}/waiting_list
GET    /locations/{location_id}/waiting_list/count
POST   /locations/{location_id}/waiting_list
GET    /locations/{location_id}/waiting_list/{waiting_list_entry_id}
PUT    /locations/{location_id}/waiting_list/{waiting_list_entry_id}
POST   /locations/{location_id}/waiting_list/{waiting_list_entry_id}/finish
DELETE /locations/{location_id}/waiting_list/{waiting_list_entry_id}
```

Start with the two collection reads because they do not require mutation:

1. verify positive list and count responses in production;
2. reconcile the responses with the current controllers, transformers, and
integration tests;
3. replace stale prose such as Client with Booking User while keeping literal
`client` and `staff` wire names in code formatting;
4. add 401, 403, and 404 responses plus the actual validation responses;
5. register only the verified GET operations in
`docs/en/b2b-v2/openapi.yaml`;
6. add both reads to the safe Arazzo workflow and require `200`, never `404`,
as proof of availability.


Minimum acceptance for this step is 34 published operations with no unverified
write contract implied by the reference.

## Step 4: Complete Waiting List only when safe

Before documenting the remaining five operations as production-verified,
confirm all of the following:

- a controlled test Booking User is available;
- create and update cannot change real customer data;
- finish does not send a notification or trigger an unsafe workflow;
- a unique run marker can identify the temporary entry;
- delete is available as cleanup after every post-create failure;
- a final list query can prove that the entry no longer exists.


When those conditions hold:

1. run create, read, update, finish, and delete against the controlled fixture;
2. capture only sanitized shapes and validation behavior;
3. finish the request and response schemas from observed production behavior;
4. register all five operations;
5. add a self-cleaning Arazzo CRUD workflow with failure cleanup; and
6. verify that no temporary entry remains.


If any safety condition is missing, stop at the read-only expansion. Document
the exact missing fixture or safety guarantee. Do not substitute a `404` probe
for a positive write contract.

Target acceptance for this step is 39 published operations.

## Step 5: Classify the remaining 21 operations

After Waiting List, rank the remaining groups using these criteria:

1. confirmed external integration use;
2. stable controller and transformer contract;
3. clear Partner and Business User authorization semantics;
4. safe positive production verification;
5. canonical domain terminology;
6. maintainable Arazzo coverage;
7. absence of backoffice-only state or UI coupling.


Recommended investigation order:

1. Units, Resource Occupations, and Custom Fields;
2. Attendance Services;
3. Attendance reads and statistics;
4. Comer Vehicles;
5. Attendance mutations, pins, and other UI-state operations.


Do not increase the public denominator for routes classified as internal.
Record that exclusion explicitly so later audits do not repeatedly rediscover
the same routes.

## Files to inspect before editing

Documentation repository:

- `docs/en/b2b-v2/openapi.yaml`
- `docs/en/paths/tags/v2/*.yml`
- `docs/en/paths/positions/v2/*.yml`
- `docs/en/paths/waiting_list/*.yml`
- `docs/en/schemas/waiting_list/*.yml`
- `docs/api-fast-check-b2b-v2.arazzo.yaml`
- `docs/api-crud-check-b2b-v2.arazzo.yaml`
- `scripts/check-b2b-v2-arazzo.mjs`


Backend repository:

- `src/Application/Http/Routing/Routes/api/api_v2.php`
- `src/Application/Http/Routing/Routes/api/modules/waiting_list.php`
- `src/Application/Http/Routing/ApiPathAliasRegistry.php`
- `src/Application/Http/Middleware/Api/ApiUrlAliasRewriteMiddleware.php`
- Waiting List controllers, transformers, services, and integration tests


Read every target file before changing it and search for references before
renaming any path file.

## Validation

Run at minimum:

```bash
npm test
./node_modules/.bin/redocly lint docs/en/b2b-v2/openapi.yaml
tools/content-scan.sh
git diff --check
```

If Arazzo changes:

```bash
make test-api-b2b-v2
```

Also:

- recount source and bundled paths and operations;
- verify every newly published operation has 401, 403, and 404;
- inspect the rendered Tags, Positions, and Waiting List pages;
- search prose for Company, Client, Staff, Record, Good, and Activity, allowing
them only as explicitly identified wire literals or compatibility paths;
- report production writes and cleanup separately from lint and source review.


## Definition of done

- Tags and Positions publish canonical Location URLs after authenticated proof.
- Compatibility `/companies` URLs remain explained without duplicated methods.
- The raw backend inventory and the approved public denominator are both known.
- At least the two Waiting List collection reads are published and live-verified.
- Full Waiting List CRUD is published only when controlled positive verification
and cleanup are complete.
- Every remaining route is marked public, internal, or needs decision.
- Redocly reports no B2B v2 warnings and the repository baseline does not regress.
- No credentials, personal data, or temporary fixtures remain.
- The final report states the new numerator and denominator and distinguishes
documented, source-verified, live-verified, and blocked operations.


## Copy-ready prompt for the next session

> Implement
`docs/plans/2026-07-16-b2b-v2-coverage-expansion.md`. Refresh both repositories
first and preserve unrelated work. Canonicalize Tags and Positions only after
authenticated `/locations` checks. Rebuild the 60-operation route inventory,
classify the 28-operation gap, and publish at least the safe Waiting List list
and count reads. Complete Waiting List writes only with a controlled Booking
User fixture, notification safety, and guaranteed cleanup. Preserve literal
wire values, use canonical prose, run all required lint and Arazzo checks, open
a focused PR, and report the final coverage ratio plus documented,
live-verified, internal, and blocked operations separately.