- Enhanced globals.css with comprehensive animation system - Added advanced map marker animations (GPS, parking) - Improved button and filter animations with hover effects - Added new UI components: BookingModal, ParkingDetails, WheelPicker - Reorganized project structure with better documentation - Added optimization scripts and improved development workflow - Updated deployment guides and technical documentation - Enhanced mobile responsiveness and accessibility support
1024 lines
26 KiB
Markdown
1024 lines
26 KiB
Markdown
# 🔌 API Schema & Data Models Documentation
|
|
|
|
## 📋 Table of Contents
|
|
1. [API Overview](#api-overview)
|
|
2. [Authentication Schema](#authentication-schema)
|
|
3. [Parking Service Schema](#parking-service-schema)
|
|
4. [Routing Service Schema](#routing-service-schema)
|
|
5. [User Management Schema](#user-management-schema)
|
|
6. [Real-time Events Schema](#real-time-events-schema)
|
|
7. [Error Handling Schema](#error-handling-schema)
|
|
|
|
---
|
|
|
|
## 🌐 API Overview
|
|
|
|
### Base Configuration
|
|
```json
|
|
{
|
|
"apiVersion": "v1",
|
|
"baseUrl": "http://localhost:3001/api",
|
|
"contentType": "application/json",
|
|
"authentication": "Bearer JWT",
|
|
"rateLimit": "100 requests/minute per user",
|
|
"timeout": "30 seconds"
|
|
}
|
|
```
|
|
|
|
### HTTP Status Codes
|
|
```json
|
|
{
|
|
"success": {
|
|
"200": "OK - Request successful",
|
|
"201": "Created - Resource created successfully",
|
|
"204": "No Content - Request successful, no response body"
|
|
},
|
|
"clientError": {
|
|
"400": "Bad Request - Invalid request data",
|
|
"401": "Unauthorized - Authentication required",
|
|
"403": "Forbidden - Insufficient permissions",
|
|
"404": "Not Found - Resource not found",
|
|
"409": "Conflict - Resource already exists",
|
|
"422": "Unprocessable Entity - Validation failed",
|
|
"429": "Too Many Requests - Rate limit exceeded"
|
|
},
|
|
"serverError": {
|
|
"500": "Internal Server Error - Server error",
|
|
"502": "Bad Gateway - External service error",
|
|
"503": "Service Unavailable - Service temporarily down"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🔐 Authentication Schema
|
|
|
|
### Login Request
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "LoginRequest",
|
|
"required": ["email", "password"],
|
|
"properties": {
|
|
"email": {
|
|
"type": "string",
|
|
"format": "email",
|
|
"description": "User's email address",
|
|
"example": "user@example.com"
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"minLength": 8,
|
|
"maxLength": 128,
|
|
"description": "User's password",
|
|
"example": "securePassword123"
|
|
},
|
|
"rememberMe": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Extended session duration"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Login Response
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "LoginResponse",
|
|
"required": ["user", "tokens"],
|
|
"properties": {
|
|
"user": {
|
|
"$ref": "#/definitions/UserProfile"
|
|
},
|
|
"tokens": {
|
|
"type": "object",
|
|
"required": ["accessToken", "refreshToken"],
|
|
"properties": {
|
|
"accessToken": {
|
|
"type": "string",
|
|
"description": "JWT access token",
|
|
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
},
|
|
"refreshToken": {
|
|
"type": "string",
|
|
"description": "JWT refresh token",
|
|
"example": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
|
|
},
|
|
"expiresIn": {
|
|
"type": "integer",
|
|
"description": "Access token expiration in seconds",
|
|
"example": 3600
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Registration Request
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "RegistrationRequest",
|
|
"required": ["email", "password", "fullName"],
|
|
"properties": {
|
|
"email": {
|
|
"type": "string",
|
|
"format": "email",
|
|
"description": "User's email address"
|
|
},
|
|
"password": {
|
|
"type": "string",
|
|
"minLength": 8,
|
|
"pattern": "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)",
|
|
"description": "Password with at least 1 lowercase, 1 uppercase, 1 digit"
|
|
},
|
|
"fullName": {
|
|
"type": "string",
|
|
"minLength": 2,
|
|
"maxLength": 100,
|
|
"description": "User's full name"
|
|
},
|
|
"phone": {
|
|
"type": "string",
|
|
"pattern": "^\\+?[1-9]\\d{1,14}$",
|
|
"description": "Phone number in international format"
|
|
},
|
|
"acceptTerms": {
|
|
"type": "boolean",
|
|
"const": true,
|
|
"description": "Must accept terms and conditions"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🅿️ Parking Service Schema
|
|
|
|
### Parking Search Request
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "ParkingSearchRequest",
|
|
"required": ["location", "radius"],
|
|
"properties": {
|
|
"location": {
|
|
"type": "object",
|
|
"required": ["latitude", "longitude"],
|
|
"properties": {
|
|
"latitude": {
|
|
"type": "number",
|
|
"minimum": -90,
|
|
"maximum": 90,
|
|
"description": "Latitude coordinate"
|
|
},
|
|
"longitude": {
|
|
"type": "number",
|
|
"minimum": -180,
|
|
"maximum": 180,
|
|
"description": "Longitude coordinate"
|
|
}
|
|
}
|
|
},
|
|
"radius": {
|
|
"type": "number",
|
|
"minimum": 100,
|
|
"maximum": 50000,
|
|
"description": "Search radius in meters"
|
|
},
|
|
"filters": {
|
|
"type": "object",
|
|
"properties": {
|
|
"maxPrice": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"description": "Maximum price per hour"
|
|
},
|
|
"amenities": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["covered", "security", "electric_charging", "disabled_access", "car_wash"]
|
|
},
|
|
"description": "Required amenities"
|
|
},
|
|
"spotTypes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["regular", "disabled", "electric", "compact"]
|
|
},
|
|
"description": "Preferred spot types"
|
|
},
|
|
"availableOnly": {
|
|
"type": "boolean",
|
|
"default": true,
|
|
"description": "Show only available parking lots"
|
|
},
|
|
"operatingHours": {
|
|
"type": "object",
|
|
"properties": {
|
|
"from": {
|
|
"type": "string",
|
|
"format": "time",
|
|
"description": "Minimum operating start time"
|
|
},
|
|
"to": {
|
|
"type": "string",
|
|
"format": "time",
|
|
"description": "Minimum operating end time"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"sorting": {
|
|
"type": "object",
|
|
"properties": {
|
|
"field": {
|
|
"type": "string",
|
|
"enum": ["distance", "price", "availability", "rating"],
|
|
"default": "distance"
|
|
},
|
|
"order": {
|
|
"type": "string",
|
|
"enum": ["asc", "desc"],
|
|
"default": "asc"
|
|
}
|
|
}
|
|
},
|
|
"pagination": {
|
|
"type": "object",
|
|
"properties": {
|
|
"page": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"default": 1
|
|
},
|
|
"limit": {
|
|
"type": "integer",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 20
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Parking Lot Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "ParkingLot",
|
|
"required": ["id", "name", "address", "coordinates", "availability", "pricing"],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid",
|
|
"description": "Unique parking lot identifier"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Parking lot name"
|
|
},
|
|
"address": {
|
|
"type": "string",
|
|
"description": "Full street address"
|
|
},
|
|
"coordinates": {
|
|
"type": "object",
|
|
"required": ["latitude", "longitude"],
|
|
"properties": {
|
|
"latitude": {
|
|
"type": "number",
|
|
"minimum": -90,
|
|
"maximum": 90
|
|
},
|
|
"longitude": {
|
|
"type": "number",
|
|
"minimum": -180,
|
|
"maximum": 180
|
|
}
|
|
}
|
|
},
|
|
"availability": {
|
|
"type": "object",
|
|
"required": ["totalSpots", "availableSpots"],
|
|
"properties": {
|
|
"totalSpots": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"availableSpots": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
},
|
|
"occupancyRate": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 1,
|
|
"description": "Percentage of occupied spots (0-1)"
|
|
},
|
|
"spotBreakdown": {
|
|
"type": "object",
|
|
"properties": {
|
|
"regular": {"type": "integer", "minimum": 0},
|
|
"disabled": {"type": "integer", "minimum": 0},
|
|
"electric": {"type": "integer", "minimum": 0},
|
|
"compact": {"type": "integer", "minimum": 0}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"pricing": {
|
|
"type": "object",
|
|
"required": ["hourlyRate", "currency"],
|
|
"properties": {
|
|
"hourlyRate": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"description": "Base hourly rate"
|
|
},
|
|
"currency": {
|
|
"type": "string",
|
|
"pattern": "^[A-Z]{3}$",
|
|
"description": "ISO 4217 currency code"
|
|
},
|
|
"discounts": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/Discount"
|
|
}
|
|
},
|
|
"timeBasedRates": {
|
|
"type": "object",
|
|
"properties": {
|
|
"peak": {
|
|
"type": "object",
|
|
"properties": {
|
|
"rate": {"type": "number", "minimum": 0},
|
|
"hours": {"type": "array", "items": {"type": "string", "format": "time"}}
|
|
}
|
|
},
|
|
"offPeak": {
|
|
"type": "object",
|
|
"properties": {
|
|
"rate": {"type": "number", "minimum": 0},
|
|
"hours": {"type": "array", "items": {"type": "string", "format": "time"}}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"operatingHours": {
|
|
"type": "object",
|
|
"patternProperties": {
|
|
"^(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$": {
|
|
"type": "object",
|
|
"properties": {
|
|
"open": {"type": "string", "format": "time"},
|
|
"close": {"type": "string", "format": "time"},
|
|
"is24Hours": {"type": "boolean", "default": false},
|
|
"isClosed": {"type": "boolean", "default": false}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"amenities": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["covered", "security", "electric_charging", "disabled_access", "car_wash", "valet", "cctv", "lighting"]
|
|
}
|
|
},
|
|
"distance": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"description": "Distance from search location in meters"
|
|
},
|
|
"estimatedWalkTime": {
|
|
"type": "integer",
|
|
"minimum": 0,
|
|
"description": "Estimated walk time in minutes"
|
|
},
|
|
"rating": {
|
|
"type": "object",
|
|
"properties": {
|
|
"average": {
|
|
"type": "number",
|
|
"minimum": 0,
|
|
"maximum": 5
|
|
},
|
|
"totalReviews": {
|
|
"type": "integer",
|
|
"minimum": 0
|
|
}
|
|
}
|
|
},
|
|
"images": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {"type": "string", "format": "uri"},
|
|
"alt": {"type": "string"},
|
|
"type": {"type": "string", "enum": ["entrance", "interior", "signage", "amenity"]}
|
|
}
|
|
}
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"properties": {
|
|
"createdAt": {"type": "string", "format": "date-time"},
|
|
"updatedAt": {"type": "string", "format": "date-time"},
|
|
"isActive": {"type": "boolean"},
|
|
"lastAvailabilityUpdate": {"type": "string", "format": "date-time"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Reservation Request Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "ReservationRequest",
|
|
"required": ["parkingLotId", "startTime", "duration"],
|
|
"properties": {
|
|
"parkingLotId": {
|
|
"type": "string",
|
|
"format": "uuid",
|
|
"description": "ID of the parking lot to reserve"
|
|
},
|
|
"spotType": {
|
|
"type": "string",
|
|
"enum": ["regular", "disabled", "electric", "compact"],
|
|
"default": "regular",
|
|
"description": "Preferred spot type"
|
|
},
|
|
"startTime": {
|
|
"type": "string",
|
|
"format": "date-time",
|
|
"description": "Reservation start time (ISO 8601)"
|
|
},
|
|
"duration": {
|
|
"type": "integer",
|
|
"minimum": 30,
|
|
"maximum": 1440,
|
|
"description": "Reservation duration in minutes"
|
|
},
|
|
"vehicleInfo": {
|
|
"type": "object",
|
|
"properties": {
|
|
"licensePlate": {
|
|
"type": "string",
|
|
"pattern": "^[A-Z0-9-]+$",
|
|
"description": "Vehicle license plate number"
|
|
},
|
|
"make": {"type": "string"},
|
|
"model": {"type": "string"},
|
|
"color": {"type": "string"}
|
|
}
|
|
},
|
|
"paymentMethod": {
|
|
"type": "string",
|
|
"enum": ["credit_card", "debit_card", "digital_wallet", "cash"],
|
|
"description": "Preferred payment method"
|
|
},
|
|
"specialRequests": {
|
|
"type": "string",
|
|
"maxLength": 500,
|
|
"description": "Additional requests or notes"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🗺️ Routing Service Schema
|
|
|
|
### Route Calculation Request
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "RouteRequest",
|
|
"required": ["origin", "destination"],
|
|
"properties": {
|
|
"origin": {
|
|
"type": "object",
|
|
"required": ["latitude", "longitude"],
|
|
"properties": {
|
|
"latitude": {"type": "number", "minimum": -90, "maximum": 90},
|
|
"longitude": {"type": "number", "minimum": -180, "maximum": 180},
|
|
"address": {"type": "string", "description": "Optional address for display"}
|
|
}
|
|
},
|
|
"destination": {
|
|
"type": "object",
|
|
"required": ["latitude", "longitude"],
|
|
"properties": {
|
|
"latitude": {"type": "number", "minimum": -90, "maximum": 90},
|
|
"longitude": {"type": "number", "minimum": -180, "maximum": 180},
|
|
"address": {"type": "string", "description": "Optional address for display"}
|
|
}
|
|
},
|
|
"transportMode": {
|
|
"type": "string",
|
|
"enum": ["driving", "walking", "cycling", "public_transit"],
|
|
"default": "driving",
|
|
"description": "Mode of transportation"
|
|
},
|
|
"preferences": {
|
|
"type": "object",
|
|
"properties": {
|
|
"avoidTolls": {"type": "boolean", "default": false},
|
|
"avoidHighways": {"type": "boolean", "default": false},
|
|
"avoidFerries": {"type": "boolean", "default": false},
|
|
"routeType": {
|
|
"type": "string",
|
|
"enum": ["fastest", "shortest", "balanced"],
|
|
"default": "fastest"
|
|
}
|
|
}
|
|
},
|
|
"waypoints": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["latitude", "longitude"],
|
|
"properties": {
|
|
"latitude": {"type": "number", "minimum": -90, "maximum": 90},
|
|
"longitude": {"type": "number", "minimum": -180, "maximum": 180},
|
|
"stopDuration": {"type": "integer", "minimum": 0, "description": "Stop duration in minutes"}
|
|
}
|
|
}
|
|
},
|
|
"alternatives": {
|
|
"type": "boolean",
|
|
"default": false,
|
|
"description": "Include alternative routes"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Route Response Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "RouteResponse",
|
|
"required": ["routes", "summary"],
|
|
"properties": {
|
|
"routes": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"required": ["geometry", "legs", "summary"],
|
|
"properties": {
|
|
"geometry": {
|
|
"type": "object",
|
|
"required": ["coordinates"],
|
|
"properties": {
|
|
"type": {"type": "string", "const": "LineString"},
|
|
"coordinates": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "array",
|
|
"items": {"type": "number"},
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
},
|
|
"description": "Array of [longitude, latitude] coordinates"
|
|
}
|
|
}
|
|
},
|
|
"legs": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"distance": {"type": "number", "description": "Distance in meters"},
|
|
"duration": {"type": "number", "description": "Duration in seconds"},
|
|
"steps": {
|
|
"type": "array",
|
|
"items": {
|
|
"$ref": "#/definitions/RouteStep"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"summary": {
|
|
"type": "object",
|
|
"required": ["distance", "duration"],
|
|
"properties": {
|
|
"distance": {"type": "number", "description": "Total distance in meters"},
|
|
"duration": {"type": "number", "description": "Total duration in seconds"},
|
|
"trafficDelay": {"type": "number", "description": "Additional time due to traffic"},
|
|
"tollCost": {"type": "number", "description": "Estimated toll cost"},
|
|
"fuelCost": {"type": "number", "description": "Estimated fuel cost"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"waypoints": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"location": {
|
|
"type": "array",
|
|
"items": {"type": "number"},
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
},
|
|
"name": {"type": "string"},
|
|
"waypointIndex": {"type": "integer"}
|
|
}
|
|
}
|
|
},
|
|
"summary": {
|
|
"type": "object",
|
|
"properties": {
|
|
"totalDistance": {"type": "string", "description": "Human-readable distance"},
|
|
"totalTime": {"type": "string", "description": "Human-readable duration"},
|
|
"estimatedCost": {"type": "number", "description": "Total estimated cost"},
|
|
"routeQuality": {
|
|
"type": "string",
|
|
"enum": ["excellent", "good", "fair", "poor"],
|
|
"description": "Route quality assessment"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 👤 User Management Schema
|
|
|
|
### User Profile Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "UserProfile",
|
|
"required": ["id", "email", "fullName"],
|
|
"properties": {
|
|
"id": {
|
|
"type": "string",
|
|
"format": "uuid",
|
|
"description": "Unique user identifier"
|
|
},
|
|
"email": {
|
|
"type": "string",
|
|
"format": "email",
|
|
"description": "User's email address"
|
|
},
|
|
"fullName": {
|
|
"type": "string",
|
|
"description": "User's full name"
|
|
},
|
|
"phone": {
|
|
"type": "string",
|
|
"pattern": "^\\+?[1-9]\\d{1,14}$",
|
|
"description": "Phone number in international format"
|
|
},
|
|
"avatar": {
|
|
"type": "string",
|
|
"format": "uri",
|
|
"description": "URL to user's avatar image"
|
|
},
|
|
"preferences": {
|
|
"type": "object",
|
|
"properties": {
|
|
"defaultTransportMode": {
|
|
"type": "string",
|
|
"enum": ["driving", "walking", "cycling", "public_transit"]
|
|
},
|
|
"defaultSearchRadius": {
|
|
"type": "number",
|
|
"minimum": 100,
|
|
"maximum": 50000
|
|
},
|
|
"preferredAmenities": {
|
|
"type": "array",
|
|
"items": {"type": "string"}
|
|
},
|
|
"notifications": {
|
|
"type": "object",
|
|
"properties": {
|
|
"email": {"type": "boolean", "default": true},
|
|
"push": {"type": "boolean", "default": true},
|
|
"sms": {"type": "boolean", "default": false},
|
|
"reservationReminders": {"type": "boolean", "default": true},
|
|
"priceAlerts": {"type": "boolean", "default": false}
|
|
}
|
|
},
|
|
"language": {
|
|
"type": "string",
|
|
"pattern": "^[a-z]{2}(-[A-Z]{2})?$",
|
|
"default": "en-US"
|
|
},
|
|
"timezone": {
|
|
"type": "string",
|
|
"description": "IANA timezone identifier"
|
|
}
|
|
}
|
|
},
|
|
"membership": {
|
|
"type": "object",
|
|
"properties": {
|
|
"tier": {
|
|
"type": "string",
|
|
"enum": ["basic", "premium", "enterprise"]
|
|
},
|
|
"joinDate": {"type": "string", "format": "date-time"},
|
|
"expiryDate": {"type": "string", "format": "date-time"},
|
|
"benefits": {
|
|
"type": "array",
|
|
"items": {"type": "string"}
|
|
}
|
|
}
|
|
},
|
|
"statistics": {
|
|
"type": "object",
|
|
"properties": {
|
|
"totalReservations": {"type": "integer", "minimum": 0},
|
|
"totalSpent": {"type": "number", "minimum": 0},
|
|
"favoriteLocations": {
|
|
"type": "array",
|
|
"items": {"type": "string", "format": "uuid"}
|
|
},
|
|
"averageRating": {"type": "number", "minimum": 0, "maximum": 5}
|
|
}
|
|
},
|
|
"metadata": {
|
|
"type": "object",
|
|
"properties": {
|
|
"createdAt": {"type": "string", "format": "date-time"},
|
|
"updatedAt": {"type": "string", "format": "date-time"},
|
|
"lastLoginAt": {"type": "string", "format": "date-time"},
|
|
"isActive": {"type": "boolean", "default": true},
|
|
"emailVerified": {"type": "boolean", "default": false},
|
|
"phoneVerified": {"type": "boolean", "default": false}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ⚡ Real-time Events Schema
|
|
|
|
### WebSocket Event Types
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "WebSocketEvent",
|
|
"required": ["type", "timestamp"],
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": [
|
|
"parking_availability_changed",
|
|
"reservation_confirmed",
|
|
"reservation_cancelled",
|
|
"route_updated",
|
|
"price_changed",
|
|
"user_location_updated"
|
|
]
|
|
},
|
|
"timestamp": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"data": {
|
|
"type": "object",
|
|
"description": "Event-specific data payload"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Parking Availability Event
|
|
```json
|
|
{
|
|
"type": "parking_availability_changed",
|
|
"timestamp": "2024-08-03T10:30:00Z",
|
|
"data": {
|
|
"parkingLotId": "uuid",
|
|
"availableSpots": 15,
|
|
"totalSpots": 50,
|
|
"spotBreakdown": {
|
|
"regular": 12,
|
|
"disabled": 2,
|
|
"electric": 1,
|
|
"compact": 0
|
|
},
|
|
"lastUpdated": "2024-08-03T10:30:00Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## ❌ Error Handling Schema
|
|
|
|
### Standard Error Response
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "ErrorResponse",
|
|
"required": ["error", "timestamp"],
|
|
"properties": {
|
|
"error": {
|
|
"type": "object",
|
|
"required": ["code", "message"],
|
|
"properties": {
|
|
"code": {
|
|
"type": "string",
|
|
"description": "Machine-readable error code"
|
|
},
|
|
"message": {
|
|
"type": "string",
|
|
"description": "Human-readable error message"
|
|
},
|
|
"details": {
|
|
"type": "object",
|
|
"description": "Additional error context"
|
|
},
|
|
"field": {
|
|
"type": "string",
|
|
"description": "Field name for validation errors"
|
|
}
|
|
}
|
|
},
|
|
"timestamp": {
|
|
"type": "string",
|
|
"format": "date-time"
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "API endpoint that caused the error"
|
|
},
|
|
"requestId": {
|
|
"type": "string",
|
|
"description": "Unique request identifier for tracking"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Validation Error Response
|
|
```json
|
|
{
|
|
"error": {
|
|
"code": "VALIDATION_ERROR",
|
|
"message": "Input validation failed",
|
|
"details": {
|
|
"violations": [
|
|
{
|
|
"field": "email",
|
|
"message": "Must be a valid email address",
|
|
"rejectedValue": "invalid-email"
|
|
},
|
|
{
|
|
"field": "password",
|
|
"message": "Must be at least 8 characters long",
|
|
"rejectedValue": "123"
|
|
}
|
|
]
|
|
}
|
|
},
|
|
"timestamp": "2024-08-03T10:30:00Z",
|
|
"path": "/api/auth/register",
|
|
"requestId": "req_123456789"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 📊 Common Definitions
|
|
|
|
### Discount Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "Discount",
|
|
"required": ["type", "value"],
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["percentage", "fixed_amount", "free_hours"]
|
|
},
|
|
"value": {"type": "number", "minimum": 0},
|
|
"description": {"type": "string"},
|
|
"conditions": {
|
|
"type": "object",
|
|
"properties": {
|
|
"minimumDuration": {"type": "integer", "minimum": 0},
|
|
"validDays": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"]
|
|
}
|
|
},
|
|
"validHours": {
|
|
"type": "object",
|
|
"properties": {
|
|
"from": {"type": "string", "format": "time"},
|
|
"to": {"type": "string", "format": "time"}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Route Step Schema
|
|
```json
|
|
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"type": "object",
|
|
"title": "RouteStep",
|
|
"required": ["instruction", "distance", "duration"],
|
|
"properties": {
|
|
"instruction": {
|
|
"type": "string",
|
|
"description": "Turn-by-turn navigation instruction"
|
|
},
|
|
"distance": {
|
|
"type": "number",
|
|
"description": "Step distance in meters"
|
|
},
|
|
"duration": {
|
|
"type": "number",
|
|
"description": "Step duration in seconds"
|
|
},
|
|
"maneuver": {
|
|
"type": "object",
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"enum": ["turn", "merge", "roundabout", "continue", "arrive"]
|
|
},
|
|
"modifier": {
|
|
"type": "string",
|
|
"enum": ["left", "right", "straight", "slight_left", "slight_right", "sharp_left", "sharp_right"]
|
|
},
|
|
"bearingBefore": {"type": "number", "minimum": 0, "maximum": 360},
|
|
"bearingAfter": {"type": "number", "minimum": 0, "maximum": 360}
|
|
}
|
|
},
|
|
"geometry": {
|
|
"type": "object",
|
|
"properties": {
|
|
"coordinates": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "array",
|
|
"items": {"type": "number"},
|
|
"minItems": 2,
|
|
"maxItems": 2
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"streetName": {"type": "string"},
|
|
"speedLimit": {"type": "integer", "minimum": 0}
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
*Last Updated: August 3, 2025*
|
|
*Version: 1.0.0*
|