openapi: "3.0.3"
info:
  title: Family Safety Tracker API
  description: REST API for sharing geolocation with family members. Authentication via JWT tokens.
  version: 1.0.0
  contact:
    name: Family Safety Tracker

servers:
  - url: http://localhost:9090
    description: Local development server

security:
  - BearerAuth: []

paths:
  /login:
    post:
      summary: Authenticate user
      description: Login with login and password. Returns a JWT token on success.
      tags:
        - Authentication
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/LoginRequest"
            example:
              login: "john_doe"
              password: "secret123"
      responses:
        "200":
          description: Authentication successful
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/LoginResponse"
              example:
                token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
        "401":
          description: Invalid credentials
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              example:
                error: "Invalid credentials"

  /reg:
    post:
      summary: Register a new user
      description: Create a new user account. Password is hashed with bcrypt.
      tags:
        - Authentication
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RegisterRequest"
            example:
              login: "john_doe"
              password: "secret123"
      responses:
        "201":
          description: User registered successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RegisterResponse"
              example:
                message: "User registered"
        "400":
          description: Bad request (e.g. login already exists)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /geo:
    put:
      summary: Update geolocation position
      description: Update the coordinates of an existing geoposition record.
      tags:
        - Geolocation
      parameters:
        - name: id
          in: query
          required: true
          description: UUID of the geoposition to update
          schema:
            type: string
            format: uuid
          example: "550e8400-e29b-41d4-a716-446655440000"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PositionRequest"
            example:
              x: 55.7558
              y: 37.6173
      responses:
        "200":
          description: Position updated successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"
              example:
                message: "Position updated"
        "401":
          description: Unauthorized - invalid or missing token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Geoposition not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /share:
    post:
      summary: Create a share link
      description: Create a new geoposition and generate a unique share link UUID for public viewing.
      tags:
        - Sharing
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PositionRequest"
            example:
              x: 55.7558
              y: 37.6173
      responses:
        "201":
          description: Share link created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ShareResponse"
              example:
                geo_id: "550e8400-e29b-41d4-a716-446655440000"
                share_id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
        "401":
          description: Unauthorized - invalid or missing token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /watch:
    get:
      summary: Get latest position via share link
      description: Retrieve the latest position for a given share link UUID. Share links are stored in-memory.
      tags:
        - Sharing
      parameters:
        - name: share_id
          in: query
          required: true
          description: UUID of the share link
          schema:
            type: string
            format: uuid
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
      responses:
        "200":
          description: Position retrieved successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PositionResponse"
              example:
                x: 55.7558
                y: 37.6173
                last_update: "2026-05-15T10:30:00.000Z"
                expires_at: "2026-05-15T11:30:00.000Z"
        "401":
          description: Unauthorized - invalid or missing token
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Share link not found or no position available
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
              examples:
                linkNotFound:
                  summary: Share link not found
                  value:
                    error: "Share link not found"
                noPosition:
                  summary: No position available
                  value:
                    error: "No position available"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT token obtained from /login. Payload contains user_id, login, and iss="family_safety_tracker".

  schemas:
    LoginRequest:
      type: object
      required:
        - login
        - password
      properties:
        login:
          type: string
          description: User login / username
          example: "john_doe"
        password:
          type: string
          format: password
          description: User password (verified against bcrypt hash)
          example: "secret123"

    RegisterRequest:
      type: object
      required:
        - login
        - password
      properties:
        login:
          type: string
          description: Desired login / username
          example: "john_doe"
        password:
          type: string
          format: password
          description: Desired password (will be hashed with bcrypt)
          example: "secret123"

    LoginResponse:
      type: object
      properties:
        token:
          type: string
          description: JWT token for authenticated requests
          example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

    RegisterResponse:
      type: object
      properties:
        message:
          type: string
          example: "User registered"

    PositionRequest:
      type: object
      required:
        - x
        - y
      properties:
        x:
          type: number
          format: double
          description: Longitude coordinate
          example: 55.7558
        y:
          type: number
          format: double
          description: Latitude coordinate
          example: 37.6173

    PositionResponse:
      type: object
      properties:
        x:
          type: number
          format: double
          description: Longitude coordinate
          example: 55.7558
        y:
          type: number
          format: double
          description: Latitude coordinate
          example: 37.6173
        last_update:
          type: string
          format: date-time
          description: Timestamp of the last position update (ISO 8601)
          example: "2026-05-15T10:30:00.000Z"
        expires_at:
          type: string
          format: date-time
          description: Expiration timestamp for the position (ISO 8601)
          example: "2026-05-15T11:30:00.000Z"

    ShareResponse:
      type: object
      properties:
        geo_id:
          type: string
          format: uuid
          description: UUID of the created geoposition record in the database
          example: "550e8400-e29b-41d4-a716-446655440000"
        share_id:
          type: string
          format: uuid
          description: UUID of the share link for public viewing
          example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890"

    MessageResponse:
      type: object
      properties:
        message:
          type: string
          example: "Position updated"

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Error description
          example: "Invalid credentials"

tags:
  - name: Authentication
    description: User registration and login
  - name: Geolocation
    description: Create and update geolocation positions
  - name: Sharing
    description: Share links for public position viewing
