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 - secret_key properties: login: type: string description: Desired login / username (minimum 5 characters) example: "john_doe" password: type: string format: password description: Desired password (minimum 9 characters, will be hashed with bcrypt) example: "securePass123" secret_key: type: string description: Plaintext registration secret key (REGISTRATION_SECRET_KEY from server .env) example: "FtracKer*1405." 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