Published on

Nave a la deriva - Interview challenge solution

Authors

TLDR: Create two endpoints (/status and /repair-bay) that work together to report and fix damaged ship systems.

This challenge belongs to a series of programming challenges published by AltScore. You can see the complete list here. This is the seventh challenge.

Problem Statement

Tu nave espacial ha sufrido daños críticos y está a la deriva en el espacio profundo. Los sistemas de la nave están fallando uno por uno, y necesitas crear un sistema de diagnóstico y reparación.

El sistema de control de la nave requiere tres endpoints:

  1. /status - Debe reportar qué sistema está dañado actualmente
  2. /repair-bay - Debe proporcionar el código de reparación del sistema dañado
  3. /teapot - Debe devolver un código HTTP 418 "I'm a teapot"

Los sistemas de la nave son:

  • navigation - Sistema de navegación
  • communications - Sistema de comunicaciones
  • life_support - Soporte vital
  • engines - Motores
  • deflector_shield - Escudo deflector

Cada sistema tiene un código de reparación único que el técnico de reparaciones necesita para arreglarlo.

Recursos:

  • Tu servidor debe estar accesible públicamente
  • Envía la URL de tu servidor aquí: [POST] /v1/s1/e7/solution
  • ¡No olvides consultar la Documentación!

Solution

Understanding the challenge

This challenge is different from the others - instead of calling APIs, we need to create APIs that AltScore will call.

The flow is:

  1. AltScore calls our /status endpoint
  2. We respond with a random damaged system
  3. AltScore calls our /repair-bay endpoint
  4. We respond with an HTML page containing the repair code for that system
  5. AltScore calls our /teapot endpoint

The tricky part is that both endpoints need to share state - the repair-bay needs to know which system was reported as damaged.

Creating the shared state

First, I created a shared state module to keep track of the current damaged system:

// app/api/shared/state.ts

export const VALID_SYSTEMS = [
  'navigation',
  'communications',
  'life_support',
  'engines',
  'deflector_shield',
] as const

type ValidSystemName = (typeof VALID_SYSTEMS)[number]

const SYSTEM_CODES: Record<ValidSystemName, string> = {
  navigation: 'NAV-01',
  communications: 'COM-02',
  life_support: 'LIFE-03',
  engines: 'ENG-04',
  deflector_shield: 'SHLD-05',
}

export const getSystemCode = (system: ValidSystemName) => {
  return SYSTEM_CODES[system]
}

let currentDamagedSystem: ValidSystemName | null = null

export const setState = (system: ValidSystemName) => {
  currentDamagedSystem = system
}

export const getState = (): ValidSystemName | null => {
  return currentDamagedSystem
}

The /status endpoint

This endpoint returns a random damaged system and stores it in the shared state:

// app/api/status/route.ts

import { NextResponse } from 'next/server'
import { setState, VALID_SYSTEMS } from '../shared/state'

export async function GET() {
  const randomSystem = VALID_SYSTEMS[Math.floor(Math.random() * VALID_SYSTEMS.length)]
  setState(randomSystem)

  return NextResponse.json({
    damaged_system: randomSystem,
  })
}

When called, it responds with:

{
  "damaged_system": "engines"
}

The /repair-bay endpoint

This endpoint returns an HTML page with the repair code inside a div with class anchor-point:

// app/api/repair-bay/route.ts

import { NextResponse } from 'next/server'
import { getState, getSystemCode } from '../shared/state'

export async function GET() {
  const currentSystem = getState()

  if (!currentSystem) {
    return new NextResponse('No damaged system reported', { status: 400 })
  }

  const systemCode = getSystemCode(currentSystem)

  const html = `
    <!DOCTYPE html>
    <html>
    <head>
        <title>Repair</title>
    </head>
    <body>
        <div class="anchor-point">${systemCode}</div>
    </body>
    </html>
  `
  return new NextResponse(html, {
    headers: {
      'Content-Type': 'text/html',
    },
  })
}

The key here is that the repair code must be inside a <div class="anchor-point"> - this is what AltScore looks for when parsing the response.

System codes mapping

SystemCode
navigationNAV-01
communicationsCOM-02
life_supportLIFE-03
enginesENG-04
deflector_shieldSHLD-05

The /teapot endpoint

This endpoint returns a HTTP 418 "I'm a teapot" response:

// app/api/teapot/route.ts

import { NextResponse } from 'next/server'

export async function POST() {
  return new NextResponse('I am a teapot', { status: 418 })
}

Deploying and testing

Since this is a Next.js app deployed on Vercel, the endpoints are automatically available at:

  • https://thedveloper.com/api/status
  • https://thedveloper.com/api/repair-bay
  • https://thedveloper.com/api/teapot

Testing locally:

# First, get the damaged system
curl http://localhost:3000/api/status
# {"damaged_system":"life_support"}

# Then, get the repair code
curl http://localhost:3000/api/repair-bay
# <!DOCTYPE html>
# <html>
# <head><title>Repair</title></head>
# <body>
#     <div class="anchor-point">LIFE-03</div>
# </body>
# </html>

Submit the solution

curl -X 'POST' \
  'https://makers-challenge.altscore.ai/v1/s1/e7/solution' \
  -H 'accept: application/json' \
  -H 'API-KEY: API-KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "url": "https://thedveloper.com"
}'

And the response is:

{
  "result": "correct"
}

Important: The endpoints need to be publicly accessible for AltScore to call them. If you're using Vercel, this works out of the box. If running locally, you'd need something like ngrok.

TADA! 🎉