Documentation and Handover: the Final Weeks Link to heading

It’s early June, and I’m in my final weeks before starting at Australian Payments Plus on June 27th. With the acquisition winding down, my focus has shifted almost entirely to documentation and handover tasks; ensuring everything is properly documented and aligned before I walk into a new office (even if it’s 100% remote, I still need to meet the team and pick up company equipment plus that generous WFH starter bonus).

This intensive documentation period has given me deep appreciation for two tools that have made API documentation and code generation seamless: Stoplight for publishing documentation with integrated mocks, and TSOA for building TypeScript routes that automatically match the docs.

Stoplight: Documentation and Mocks in One Link to heading

In these final weeks, getting our API documentation perfect has been critical. Stoplight has been a game-changer; it’s a SaaS platform that takes OpenAPI specifications and creates beautiful, interactive documentation with integrated mock servers.

The magic happens when you publish a new version: the documentation updates instantly, and the mocks are automatically available at the same endpoints. No more maintaining separate mock servers or worrying about documentation drift.

Real-World Example from Our Handover Link to heading

Here’s one of the API specifications I’ve been documenting for handover:

openapi: 3.0.3
info:
  title: Task Management API
  description: API for managing tasks and projects
  version: 1.0.0
  contact:
    name: API Support
    email: support@example.com

servers:
  - url: https://api.example.com/v1
    description: Production server
  - url: https://staging-api.example.com/v1
    description: Staging server

paths:
  /tasks:
    get:
      summary: List tasks
      description: Retrieve a list of tasks with optional filtering
      parameters:
        - name: status
          in: query
          description: Filter tasks by status
          schema:
            type: string
            enum: [pending, in_progress, completed]
        - name: limit
          in: query
          description: Maximum number of tasks to return
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of tasks to skip
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        "200":
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  tasks:
                    type: array
                    items:
                      $ref: "#/components/schemas/Task"
                  pagination:
                    $ref: "#/components/schemas/PaginationInfo"

    post:
      summary: Create a new task
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateTaskRequest"
      responses:
        "201":
          description: Task created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Task"
        "400":
          description: Invalid request data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

components:
  schemas:
    Task:
      type: object
      required:
        - id
        - title
        - status
        - created_at
      properties:
        id:
          type: string
          format: uuid
          example: "123e4567-e89b-12d3-a456-426614174000"
        title:
          type: string
          maxLength: 200
          example: "Complete API documentation"
        description:
          type: string
          maxLength: 1000
          example: "Write comprehensive API documentation using OpenAPI"
        status:
          type: string
          enum: [pending, in_progress, completed]
          example: "pending"
        priority:
          type: string
          enum: [low, medium, high, urgent]
          default: "medium"
        due_date:
          type: string
          format: date-time
          example: "2022-06-15T09:00:00Z"
        created_at:
          type: string
          format: date-time
          example: "2022-06-09T13:10:00Z"
        updated_at:
          type: string
          format: date-time
          example: "2022-06-09T13:10:00Z"

    CreateTaskRequest:
      type: object
      required:
        - title
      properties:
        title:
          type: string
          maxLength: 200
        description:
          type: string
          maxLength: 1000
        priority:
          type: string
          enum: [low, medium, high, urgent]
          default: "medium"
        due_date:
          type: string
          format: date-time

    PaginationInfo:
      type: object
      properties:
        total:
          type: integer
          example: 150
        limit:
          type: integer
          example: 20
        offset:
          type: integer
          example: 0
        has_next:
          type: boolean
          example: true

    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          properties:
            type:
              type: string
              example: "validation_error"
            message:
              type: string
              example: "The request contains invalid data"
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string

  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

security:
  - BearerAuth: []

TSOA: Code Generation That Actually Works Link to heading

The other revelation has been TSOA (TypeScript OpenAPI). Instead of maintaining OpenAPI specs separately from code, TSOA generates the specifications automatically from TypeScript decorators on your route handlers.

This solves the fundamental problem: keeping documentation in sync with implementation. With TSOA, the docs are built from the code, so they can’t drift apart.

Building Routes with TSOA Link to heading

Here’s what a typical controller looks like:

import { Controller, Get, Post, Body, Route, Tags, Query, Path } from "tsoa"

@Route("tasks")
@Tags("Tasks")
export class TasksController extends Controller {
  @Get()
  public async getTasks(@Query() status?: "pending" | "in_progress" | "completed", @Query() limit: number = 20, @Query() offset: number = 0): Promise<TaskListResponse> {
    // Implementation here
    const tasks = await this.taskService.findTasks({ status, limit, offset })
    return {
      tasks,
      pagination: {
        total: await this.taskService.countTasks({ status }),
        limit,
        offset,
        hasNext: tasks.length === limit,
      },
    }
  }

  @Post()
  public async createTask(@Body() requestBody: CreateTaskRequest): Promise<Task> {
    this.setStatus(201)
    return await this.taskService.createTask(requestBody)
  }

  @Get("{id}")
  public async getTask(@Path() id: string): Promise<Task> {
    const task = await this.taskService.findById(id)
    if (!task) {
      this.setStatus(404)
      throw new Error("Task not found")
    }
    return task
  }
}

The Magic Build Process Link to heading

TSOA reads these decorators and generates:

  1. OpenAPI specification
  2. Express route handlers
  3. TypeScript interfaces
# Generate OpenAPI spec and routes
npx tsoa spec-and-routes

# This creates:
# - public/swagger.json (OpenAPI spec)
# - src/routes.ts (Express routes)

The generated routes file handles all the request validation, parameter parsing, and response formatting automatically.

The Perfect Integration: TSOA + Stoplight Link to heading

The magic happens when you combine both tools:

  1. Write TSOA controllers with TypeScript decorators
  2. Generate OpenAPI spec automatically from the code
  3. Publish to Stoplight for beautiful documentation and instant mocks
  4. Build routes knowing they perfectly match the docs

This workflow has been critical during handover. Every API endpoint is documented, mocked, and implemented in perfect sync. The incoming team can see exactly how each endpoint works, test against live mocks, and understand the complete API surface area.

Handover Mode: Documentation Everything Link to heading

With just weeks left before starting my new role, this toolchain has been essential. Instead of frantically writing documentation that might drift from reality, I can:

  • Focus on business logic documentation since API docs are generated
  • Provide working mocks immediately via Stoplight publishing
  • Ensure zero documentation debt for the acquiring team
  • Demonstrate API usage through interactive Stoplight docs

Looking Forward to AP+ Link to heading

Starting June 27th, I’ll be walking into the AP+ offices (even though it’s 100% remote) to meet the team and pick up company equipment. The generous WFH starter bonus shows they understand the modern remote-first setup needs.

After months of handover documentation, I’m looking forward to building rather than documenting. The experience with Stoplight and TSOA has shown me how powerful the right tooling can be for maintaining API quality and team communication.

Final Weeks Reflection Link to heading

These last weeks have reinforced how critical good documentation is during transitions. When you’re handing off systems to another team, having perfectly aligned documentation and implementation isn’t just nice-to-have; it’s essential.

The combination of TSOA’s code-first generation and Stoplight’s publishing platform has eliminated the documentation-reality gap that usually exists during handovers. Every endpoint works exactly as documented because the docs are built from the same source as the implementation.

The workflow is simple but powerful:

  1. Build APIs with TSOA decorators in TypeScript
  2. Generate OpenAPI specs automatically
  3. Publish to Stoplight for instant documentation and mocks
  4. Hand off systems that are perfectly documented

As I finish up these final weeks and prepare to start at AP+ on June 27th, this toolchain has been invaluable. The acquiring team gets APIs that are documented, mocked, and aligned; no documentation debt, no guessing about how endpoints work.

Looking forward to the rest of the year and what we can build when the focus shifts from documenting to creating.


Have you used TSOA or Stoplight for API development? How do you handle documentation during major transitions or handovers?