Add batch management APIs, API security, rate limiting, and optimizations
- Batch device CRUD: POST /api/devices/batch (create 500), PUT /api/devices/batch (update 500), POST /api/devices/batch-delete (delete 100) with WHERE IN bulk queries - Batch command: POST /api/commands/batch with model_validator mutual exclusion - API key auth (X-API-Key header, secrets.compare_digest timing-safe) - Rate limiting via SlowAPIMiddleware (60/min default, 30/min writes) - Real client IP extraction (X-Forwarded-For / CF-Connecting-IP) - Global exception handler (no stack trace leaks, passes HTTPException through) - CORS with auto-disable credentials on wildcard origins - Schema validation: IMEI pattern, lat/lon ranges, Literal enums, MAC/UUID patterns - Heartbeats router, per-ID endpoints for locations/attendance/bluetooth - Input dedup in batch create, result ordering preserved - Baidu reverse geocoding, Gaode map tiles with WGS84→GCJ02 conversion - Device detail panel with feature toggles and command controls - Side panel for location/beacon pages with auto-select active device via [HAPI](https://hapi.run) Co-Authored-By: HAPI <noreply@hapi.run>
This commit is contained in:
@@ -136,6 +136,57 @@ PROTOCOLS_REQUIRING_RESPONSE: FrozenSet[int] = frozenset({
|
||||
# Note: PROTO_BT_LOCATION (0xB3) does NOT require a response per protocol spec
|
||||
})
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Device Defaults
|
||||
# ---------------------------------------------------------------------------
|
||||
DEFAULT_DEVICE_TYPE: str = "P240"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Language Codes (used in 0x80 / 0x82 packets)
|
||||
# ---------------------------------------------------------------------------
|
||||
LANG_CHINESE: int = 0x0001
|
||||
LANG_ENGLISH: int = 0x0002
|
||||
DEFAULT_LANGUAGE: int = LANG_CHINESE
|
||||
DEFAULT_LANGUAGE_BYTES: bytes = b"\x00\x01"
|
||||
|
||||
# Server flag placeholder (4 bytes, used in command/message packets)
|
||||
SERVER_FLAG_BYTES: bytes = b"\x00\x00\x00\x00"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Attendance Status (from terminal_info byte, bits[5:2])
|
||||
# ---------------------------------------------------------------------------
|
||||
ATTENDANCE_STATUS_SHIFT: int = 2
|
||||
ATTENDANCE_STATUS_MASK: int = 0x0F
|
||||
ATTENDANCE_TYPES: Dict[int, str] = {
|
||||
0b0001: "clock_in",
|
||||
0b0010: "clock_out",
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# GPS Course/Status Bit Fields
|
||||
# ---------------------------------------------------------------------------
|
||||
COURSE_BIT_REALTIME: int = 0x2000 # bit 13
|
||||
COURSE_BIT_POSITIONED: int = 0x1000 # bit 12
|
||||
COURSE_BIT_EAST: int = 0x0800 # bit 11
|
||||
COURSE_BIT_NORTH: int = 0x0400 # bit 10
|
||||
COURSE_MASK: int = 0x03FF # bits 9-0
|
||||
|
||||
# MCC high-bit flag: if set, MNC is 2 bytes instead of 1
|
||||
MCC_MNC2_FLAG: int = 0x8000
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Voltage Levels (0x00-0x06)
|
||||
# ---------------------------------------------------------------------------
|
||||
VOLTAGE_LEVELS: Dict[int, str] = {
|
||||
0x00: "shutdown",
|
||||
0x01: "very_low",
|
||||
0x02: "low",
|
||||
0x03: "medium",
|
||||
0x04: "good",
|
||||
0x05: "high",
|
||||
0x06: "full",
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Protocol Number -> Human-Readable Name
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user