From a9d9951a7e7aa6180a221bc6170ad8aa73abdfe5 Mon Sep 17 00:00:00 2001 From: "dmit.b" Date: Fri, 15 May 2026 18:00:45 +0300 Subject: [PATCH] fix ignore --- .gitignore | 6 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + opencode.json | 137 ++- web/swagger/swagger.yaml | 803 ++++++------------ 4 files changed, 397 insertions(+), 551 deletions(-) diff --git a/.gitignore b/.gitignore index 3820a95..7ab41ed 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,9 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + + +/build +/AGENTS.md +/opencode.json +/tools diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index d7ee0bc..8679ef3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,8 +7,10 @@ import Foundation import geolocator_apple import package_info_plus +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/opencode.json b/opencode.json index f36bf6d..aed759e 100644 --- a/opencode.json +++ b/opencode.json @@ -1,28 +1,139 @@ { "$schema": "https://opencode.ai/config.json", + "server": { + "port": 4096, + "hostname": "0.0.0.0" + }, + "compaction": { + "auto": false + }, + "autoupdate": false, + "model": "llama_swap/Qwen3.6-35B-A3B-Q8_0_img", + "small_model": "llama_swap/cpu_gemma4-E2B-Q4_K_M", "provider": { - "llama.cpp": { + "llama_swap": { + "name": "llama_swap", "npm": "@ai-sdk/openai-compatible", - "name": "llama-server (local)", - "options": { - "baseURL": "http://127.0.0.1:9988/v1" - }, "models": { - "qwen3-coder:a3b": { - "name": "Qwen_Qwen3.5-9B-Q6_K (local)", + "Qwen3.6-35B-A3B-Q8_0_img": { + "name": "Qwen3.6-35B-A3B-Q8_0_img", + "tool_call": true, + "reasoning": true, "limit": { - "context": 248000, - "output": 65655 + "context": 196608, + "output": 83968 + }, + "modalities": { + "input": ["text", "image", "pdf"], + "output": ["text"] + } + }, + "Qwen3.6-35B-A3B-Q8_0_fullctx": { + "name": "Qwen3.6-35B-A3B-Q8_0_fullctx", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 262144, + "output": 83968 + }, + "modalities": { + "input": ["text"], + "output": ["text"] + } + }, + "google_gemma-4-E4B-it-Q4_K_M": { + "name": "google_gemma-4-E4B-it-Q4_K_M", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 262144, + "output": 65536 + }, + "modalities": { + "input": ["text", "image", "pdf", "audio", "video"], + "output": ["text"] + } + }, + "GRM-2.6-Plus-Q8_0": { + "name": "GRM-2.6-Plus-Q8_0", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 196608, + "output": 83968 + }, + "modalities": { + "input": ["text", "image", "pdf"], + "output": ["text"] + } + }, + "cpu_gemma4-E2B-Q4_K_M": { + "name": "cpu_gemma4-E2B-Q4_K_M", + "tool_call": false, + "reasoning": false, + "limit": { + "context": 16384, + "output": 16384 + }, + "modalities": { + "input": ["text"], + "output": ["text"] + } + }, + "Qwopus3.5-27B-v3-Q8_0": { + "name": "Qwopus3.5-27B-v3-Q8_0", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 262144, + "output": 83968 + }, + "modalities": { + "input": ["text"], + "output": ["text"] + } + }, + "Qwopus3.6-27B-v1-preview-Q8_0": { + "name": "Qwopus3.6-27B-v1-preview-Q8_0", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 262144, + "output": 83968 + }, + "modalities": { + "input": ["text"], + "output": ["text"] + } + }, + "Qwopus3.6-35B-A3B-v1-Q8_0": { + "name": "Qwopus3.6-35B-A3B-v1-Q8_0", + "tool_call": true, + "reasoning": true, + "limit": { + "context": 262144, + "output": 83968 + }, + "modalities": { + "input": ["text"], + "output": ["text"] } } + }, + "options": { + "baseURL": "https://ai.shstk.ru/v1", + "apiKey": "shs.passwd" } } }, "mcp": { - "IntelliJIdea": { - "type": "remote", - "url": "http://127.0.0.1:64342/stream", + "chrome-devtools": { + "type": "local", + "command": ["/home/andrey/chrome-devtools-mcp-venv/bin/python", "/home/andrey/chrome-devtools-mcp/server.py"], + "environment": { + "CHROME_DEBUG_PORT": "9222" + }, "enabled": true } } -} \ No newline at end of file +} diff --git a/web/swagger/swagger.yaml b/web/swagger/swagger.yaml index 9485fd3..8cd9f68 100644 --- a/web/swagger/swagger.yaml +++ b/web/swagger/swagger.yaml @@ -1,619 +1,346 @@ -openapi: 3.0.0 +openapi: "3.0.3" info: - title: Mesh backend REST API + title: Family Safety Tracker API + description: REST API for sharing geolocation with family members. Authentication via JWT tokens. version: 1.0.0 - description: Описание API + contact: + name: Family Safety Tracker + servers: - - url: http://localhost:8888/api + - url: http://localhost:9090 + description: Local development server + +security: + - BearerAuth: [] + paths: - /info: - get: - tags: - - Common - summary: Запрос статуса сервера - responses: - '200': - description: On success - content: - application/json: - schema: - $ref: '#/components/schemas/BackendInfo' - /blockRule: - get: - tags: - - BlockRule - summary: Запрос правил блокировок - responses: - '200': - description: On success - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/BlockPriorityRule' - delete: - tags: - - BlockRule - summary: Удалить правило - requestBody: - description: Удалить правило - content: - application/json: - schema: - $ref: '#/components/schemas/BlockPriorityRule' - required: true - responses: - '200': - description: On success - '400': - description: On error - '404': - description: Не найдено + /login: post: + summary: Authenticate user + description: Login with login and password. Returns a JWT token on success. tags: - - BlockRule - summary: Добавить правило блокировки + - Authentication + security: [] requestBody: - description: Правило блокировки (объект json) + required: true content: application/json: schema: - $ref: '#/components/schemas/BlockPriorityRule' - required: true + $ref: "#/components/schemas/LoginRequest" + example: + login: "john_doe" + password: "secret123" responses: - '200': - description: On success - '400': - description: On error - /priorityRule: - get: - tags: - - PriorityRule - summary: Запрос правил приоритета (Qos) - responses: - '200': - description: On success + "200": + description: Authentication successful + headers: + Access-Control-Allow-Origin: + schema: + type: string content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/BlockPriorityRule' - delete: - tags: - - PriorityRule - summary: Удалить правила приоритета - requestBody: - description: Удалить правило приоритета (Qos) - content: - application/json: - schema: - $ref: '#/components/schemas/BlockPriorityRule' - required: true - responses: - '200': - description: On success - '400': - description: On error - '404': - description: Не найдено + $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: - - PriorityRule - summary: Добавить правило приоритета (Qos) + - Authentication + security: [] requestBody: - description: Правило приоритета (Qos) (объект json) - content: - application/json: - schema: - $ref: '#/components/schemas/BlockPriorityRule' required: true + content: + application/json: + schema: + $ref: "#/components/schemas/RegisterRequest" + example: + login: "john_doe" + password: "secret123" responses: - '200': - description: On success - '400': - description: On error - /interface: - get: - tags: - - Interface - summary: Запрос сетевых интерфейсов - responses: - '200': - description: On success + "201": + description: User registered successfully content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Interface' + $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: - - Interface - summary: Обновить интерфейс + - Geolocation parameters: - - name: interface + - name: id in: query - description: Interface object required: true + description: UUID of the geoposition to update schema: - $ref: '#/components/schemas/Interface' + type: string + format: uuid + example: "550e8400-e29b-41d4-a716-446655440000" requestBody: - description: Обновить интерфейс + required: true content: application/json: schema: - $ref: '#/components/schemas/Interface' - required: true + $ref: "#/components/schemas/PositionRequest" + example: + x: 55.7558 + y: 37.6173 responses: - '200': - description: On success - '400': - description: On error - /config: - get: - tags: - - Config - summary: Запрос настроек - responses: - '200': - description: On success + "200": + description: Position updated successfully content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Config' - put: - tags: - - Config - summary: Обновить настройки - parameters: - - name: Config - in: query - description: Config object - required: true - schema: - $ref: '#/components/schemas/Config' - requestBody: - description: Обновить Config - content: - application/json: - schema: - $ref: '#/components/schemas/Config' - required: true - responses: - '200': - description: On success - '400': - description: On error - /stats: - get: - tags: - - Common - summary: Запрос статистики сервера - responses: - '200': - description: On success + $ref: "#/components/schemas/MessageResponse" + example: + message: "Position updated" + "401": + description: Unauthorized - invalid or missing token content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Stat' - /commandList: - get: - tags: - - CommandList - summary: Запрос списка команд - responses: - '200': - description: On success + $ref: "#/components/schemas/ErrorResponse" + "404": + description: Geoposition not found content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/Command' - put: - tags: - - CommandList - summary: Перезапись списка команд - requestBody: - description: Перезапись списка команд - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/Command' - responses: - '200': - description: On success - /commandRun/{id}: + $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: - - CommandRun - summary: Запустить команду - parameters: - - name: id - in: path - description: ID of command - required: true - schema: - type: string - responses: - '200': - description: On success - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/CommandResult' - '400': - description: On error - '404': - description: Не найдено - '405': - description: Конфиг нельзя запустить - delete: - tags: - - CommandRun - summary: Остановить команду - parameters: - - name: id - in: path - description: ID of command - required: true - schema: - type: string - responses: - '200': - description: On success - content: - application/json: - schema: - type: array - items: - $ref: '#/components/schemas/CommandResult' - '400': - description: On error - /command: - post: - tags: - - Command - summary: Добавить команду - parameters: - - name: command - in: query - description: Command object - required: true - schema: - $ref: '#'#/components/schemas/Command' + - Sharing requestBody: - description: Добавить команду + required: true content: application/json: schema: - $ref: '#/components/schemas/Command' - required: true + $ref: "#/components/schemas/PositionRequest" + example: + x: 55.7558 + y: 37.6173 responses: - '200': - description: Успех - '400': - description: ID занят - '409': - description: Конфиг или скрипт уже существуют - get: - tags: - - Command - summary: Запросить команду с телом - parameters: - - name: id - in: query - description: Command ID - required: true - schema: - type: string - responses: - '200': - description: On success - '400': - description: On error - delete: - tags: - - Command - summary: Удалить команду - parameters: - - name: id - in: query - description: Command ID - required: true - schema: - type: string - responses: - '200': - description: On success - '400': - description: On error - '404': - description: Не найдено - put: - tags: - - Command - summary: Обновить команду - parameters: - - name: command - in: query - description: Command object - required: true - schema: - $ref: '#'#/components/schemas/Command' - requestBody: - description: Обновить команду - content: - application/json: - schema: - $ref: '#/components/schemas/Command' - required: true - responses: - '200': - description: On success - '400': - description: On error - /commandStatuses: - get: - tags: - - CommandStatus - summary: Запрос статусов выполнения команд - responses: - '200': - description: On success + "201": + description: Share link created successfully content: application/json: schema: - type: array - items: - $ref: '#/components/schemas/CommandResult' - '400': - description: On error - /graphInfo: - get: - tags: - - NodeInfo - summary: Запрос связей между точками - responses: - '200': - description: On success + $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: - type: array - items: - $ref: '#/components/schemas/NodeInfo' - '400': - description: On error - /hotspot: + $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: - - Hotspot - summary: Запросить информацию о точке + - Sharing parameters: - - name: id + - name: share_id in: query - description: Hotspot ID required: true + description: UUID of the share link schema: type: string + format: uuid + example: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" responses: - '200': - description: On success - '400': - description: On error + "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: - Interface: + 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: - name: + token: type: string - default: eth0 - ip: - type: string - default: 192.168.1.1 - netmask: - type: string - default: 255.255.255.0 - mac: - type: string - default: 4A:30:10:21:10:1A - mtu: - type: integer - default: 0 - active: - type: boolean - default: true - loopback: - type: boolean - default: false - readonly: - type: boolean - default: false - Config: + description: JWT token for authenticated requests + example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." + + RegisterResponse: type: object properties: - secret: + message: type: string - default: error - channel: - type: integer - default: 0 - width: - type: integer - default: 0 - power: - type: integer - default: 0 - distance: - type: integer - default: 0 - Command: + 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: - id: + 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 - default: error - contentType: + format: date-time + description: Timestamp of the last position update (ISO 8601) + example: "2026-05-15T10:30:00.000Z" + expires_at: type: string - default: error - path: - type: string - default: error - content: - type: string - default: error - needConfirmation: - type: boolean - default: false - CommandResult: + format: date-time + description: Expiration timestamp for the position (ISO 8601) + example: "2026-05-15T11:30:00.000Z" + + ShareResponse: type: object properties: - id: + geo_id: type: string - default: "name unknown" - exitCode: - type: integer - default: 0 - output: + format: uuid + description: UUID of the created geoposition record in the database + example: "550e8400-e29b-41d4-a716-446655440000" + share_id: type: string - default: "command stdout" + 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 - default: "command stderr" - running: - type: boolean - default: false - Stat: - type: object - properties: - name: - type: string - default: "unknown" - spots: - type: array - items: - type: number - default: 0.0 - interval: - type: integer - default: 5 - units: - type: string - default: "db" - min: - type: number - default: 0.0 - max: - type: number - default: 100.0 - HotspotInfo: - type: object - properties: - name: - type: string - default: "unknown" - signal: - type: number - default: 0.0 - hops: - type: integer - default: 5 - rx: - type: integer - default: 5 - tx: - type: integer - default: 5 - bytesReceived: - type: integer - default: 5 - bytesSent: - type: integer - default: 5 - connectionTime: - type: integer - default: 5, - inactiveTime: - type: integer - default: 5, - stats: - type: array - items: - $ref: '#/components/schemas/Stat' - BackendInfo: - type: object - properties: - version: - type: string - default: "unknown" - arch: - type: string - default: "unknown" - uptime: - type: integer - default: 0 - hostname: - type: string - default: "unknown" - buildNum: - type: integer - default: 9999 - buildType: - type: string - default: "unknown" - buildDate: - type: string - default: "unknown" - pipVersion: - type: string - default: "unknown" - frontVersion: - type: string - default: "unknown" - frontBuild: - type: string - default: "unknown" - NodeInfo: - type: object - properties: - mac: - type: string - default: "unknown" - connections: - type: array - items: - type: string - default: node - BlockPriorityRule: - type: object - properties: - name: - type: string - default: "unknown" - protocol: - type: string - default: "tcp" - port: - type: integer - default: 389 - allow: - type: boolean - default: false - direction: - type: boolean - default: true - priority: - type: integer - default: 0 \ No newline at end of file + 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