Files
Laca-City/Documents/API_SCHEMA.md
PhongPham e0e47d57c7 feat: Enhanced CSS animations, improved UI components, and project reorganization
- 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
2025-08-03 07:00:22 +07:00

26 KiB

🔌 API Schema & Data Models Documentation

📋 Table of Contents

  1. API Overview
  2. Authentication Schema
  3. Parking Service Schema
  4. Routing Service Schema
  5. User Management Schema
  6. Real-time Events Schema
  7. Error Handling Schema

🌐 API Overview

Base Configuration

{
  "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

{
  "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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "$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

{
  "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

{
  "$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

{
  "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

{
  "$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

{
  "$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