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
This commit is contained in:
1023
Documents/API_SCHEMA.md
Normal file
1023
Documents/API_SCHEMA.md
Normal file
File diff suppressed because it is too large
Load Diff
839
Documents/DATABASE_DESIGN.md
Normal file
839
Documents/DATABASE_DESIGN.md
Normal file
@@ -0,0 +1,839 @@
|
||||
# 🗄️ Database Design & Data Structure Documentation
|
||||
|
||||
## 📋 Table of Contents
|
||||
1. [Database Overview](#database-overview)
|
||||
2. [Entity Relationship Diagram](#entity-relationship-diagram)
|
||||
3. [Table Specifications](#table-specifications)
|
||||
4. [Indexes & Performance](#indexes--performance)
|
||||
5. [Data Migration Strategy](#data-migration-strategy)
|
||||
6. [Backup & Recovery](#backup--recovery)
|
||||
7. [Scaling Considerations](#scaling-considerations)
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Database Overview
|
||||
|
||||
### Technology Stack
|
||||
```json
|
||||
{
|
||||
"primary_database": "PostgreSQL 15.x",
|
||||
"cache_layer": "Redis 7.x",
|
||||
"orm": "TypeORM",
|
||||
"connection_pooling": "pg_pool",
|
||||
"backup_strategy": "Continuous WAL archiving",
|
||||
"monitoring": "PostgreSQL Stats + Custom metrics"
|
||||
}
|
||||
```
|
||||
|
||||
### Database Characteristics
|
||||
- **ACID Compliance**: Full ACID transaction support
|
||||
- **Concurrency**: Multi-version concurrency control (MVCC)
|
||||
- **Extensibility**: PostGIS for spatial operations
|
||||
- **Performance**: Optimized indexes for geospatial queries
|
||||
- **Scalability**: Read replicas and partitioning strategies
|
||||
|
||||
---
|
||||
|
||||
## 🔗 Entity Relationship Diagram
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
Users ||--o{ Reservations : makes
|
||||
Users ||--o{ Reviews : writes
|
||||
Users ||--o{ Favorites : has
|
||||
Users ||--o{ Payments : processes
|
||||
|
||||
ParkingLots ||--o{ ParkingSpots : contains
|
||||
ParkingLots ||--o{ Reservations : receives
|
||||
ParkingLots ||--o{ Reviews : receives
|
||||
ParkingLots ||--o{ Favorites : featured_in
|
||||
ParkingLots ||--o{ PricingRules : has
|
||||
ParkingLots }|--|| Operators : managed_by
|
||||
|
||||
ParkingSpots ||--o{ Reservations : reserved_for
|
||||
ParkingSpots ||--o{ SpotHistory : tracks
|
||||
|
||||
Reservations ||--|| Payments : triggers
|
||||
Reservations ||--o{ ReservationHistory : logs
|
||||
|
||||
Operators ||--o{ ParkingLots : manages
|
||||
Operators ||--o{ OperatorUsers : employs
|
||||
|
||||
Users {
|
||||
uuid id PK
|
||||
string email UK
|
||||
string password_hash
|
||||
string full_name
|
||||
string phone
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
boolean is_active
|
||||
user_role role
|
||||
}
|
||||
|
||||
ParkingLots {
|
||||
uuid id PK
|
||||
string name
|
||||
text address
|
||||
decimal latitude
|
||||
decimal longitude
|
||||
integer total_spots
|
||||
integer available_spots
|
||||
decimal price_per_hour
|
||||
jsonb operating_hours
|
||||
text[] amenities
|
||||
uuid operator_id FK
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
boolean is_active
|
||||
}
|
||||
|
||||
ParkingSpots {
|
||||
uuid id PK
|
||||
uuid parking_lot_id FK
|
||||
string spot_number
|
||||
spot_type type
|
||||
boolean is_occupied
|
||||
boolean is_reserved
|
||||
timestamp last_updated
|
||||
}
|
||||
|
||||
Reservations {
|
||||
uuid id PK
|
||||
uuid user_id FK
|
||||
uuid parking_spot_id FK
|
||||
timestamp start_time
|
||||
timestamp end_time
|
||||
decimal total_cost
|
||||
reservation_status status
|
||||
timestamp created_at
|
||||
timestamp updated_at
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Table Specifications
|
||||
|
||||
### 1. Users Table
|
||||
|
||||
```sql
|
||||
CREATE TYPE user_role AS ENUM ('customer', 'operator', 'admin');
|
||||
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20),
|
||||
avatar_url TEXT,
|
||||
|
||||
-- Preferences stored as JSONB for flexibility
|
||||
preferences JSONB DEFAULT '{}',
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
last_login_at TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Status fields
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
email_verified BOOLEAN DEFAULT FALSE,
|
||||
phone_verified BOOLEAN DEFAULT FALSE,
|
||||
role user_role DEFAULT 'customer',
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT valid_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$'),
|
||||
CONSTRAINT valid_phone CHECK (phone IS NULL OR phone ~* '^\+?[1-9]\d{1,14}$')
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_users_email ON users (email);
|
||||
CREATE INDEX idx_users_role_active ON users (role, is_active);
|
||||
CREATE INDEX idx_users_created_at ON users (created_at);
|
||||
|
||||
-- Update trigger
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER update_users_updated_at
|
||||
BEFORE UPDATE ON users
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION update_updated_at_column();
|
||||
```
|
||||
|
||||
### 2. Operators Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE operators (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
company_name VARCHAR(255) NOT NULL,
|
||||
contact_email VARCHAR(255) NOT NULL,
|
||||
contact_phone VARCHAR(20),
|
||||
address TEXT,
|
||||
|
||||
-- Business information
|
||||
business_license VARCHAR(100),
|
||||
tax_id VARCHAR(50),
|
||||
|
||||
-- Settings
|
||||
commission_rate DECIMAL(5,4) DEFAULT 0.1000, -- 10% default
|
||||
auto_approval BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
|
||||
CONSTRAINT valid_commission_rate CHECK (commission_rate >= 0 AND commission_rate <= 1)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_operators_active ON operators (is_active);
|
||||
CREATE INDEX idx_operators_company_name ON operators (company_name);
|
||||
```
|
||||
|
||||
### 3. Parking Lots Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE parking_lots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
operator_id UUID REFERENCES operators(id) ON DELETE CASCADE,
|
||||
|
||||
-- Basic information
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT,
|
||||
address TEXT NOT NULL,
|
||||
|
||||
-- Geolocation (using decimal for precision)
|
||||
latitude DECIMAL(10,8) NOT NULL,
|
||||
longitude DECIMAL(11,8) NOT NULL,
|
||||
|
||||
-- Capacity
|
||||
total_spots INTEGER NOT NULL DEFAULT 0,
|
||||
available_spots INTEGER NOT NULL DEFAULT 0,
|
||||
|
||||
-- Pricing
|
||||
price_per_hour DECIMAL(10,2) NOT NULL,
|
||||
currency CHAR(3) DEFAULT 'USD',
|
||||
|
||||
-- Operating hours stored as JSONB for flexibility
|
||||
operating_hours JSONB DEFAULT '{
|
||||
"monday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"tuesday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"wednesday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"thursday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"friday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"saturday": {"open": "00:00", "close": "23:59", "is24Hours": true},
|
||||
"sunday": {"open": "00:00", "close": "23:59", "is24Hours": true}
|
||||
}',
|
||||
|
||||
-- Amenities as array
|
||||
amenities TEXT[] DEFAULT '{}',
|
||||
|
||||
-- Images
|
||||
images JSONB DEFAULT '[]',
|
||||
|
||||
-- Ratings
|
||||
average_rating DECIMAL(3,2) DEFAULT 0,
|
||||
total_reviews INTEGER DEFAULT 0,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
last_availability_update TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE,
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT valid_coordinates CHECK (
|
||||
latitude BETWEEN -90 AND 90 AND
|
||||
longitude BETWEEN -180 AND 180
|
||||
),
|
||||
CONSTRAINT valid_capacity CHECK (
|
||||
total_spots >= 0 AND
|
||||
available_spots >= 0 AND
|
||||
available_spots <= total_spots
|
||||
),
|
||||
CONSTRAINT valid_price CHECK (price_per_hour >= 0),
|
||||
CONSTRAINT valid_rating CHECK (average_rating BETWEEN 0 AND 5)
|
||||
);
|
||||
|
||||
-- Spatial index for location-based queries
|
||||
CREATE INDEX idx_parking_lots_location ON parking_lots
|
||||
USING GIST (ll_to_earth(latitude, longitude));
|
||||
|
||||
-- Regular indexes
|
||||
CREATE INDEX idx_parking_lots_operator ON parking_lots (operator_id);
|
||||
CREATE INDEX idx_parking_lots_active ON parking_lots (is_active);
|
||||
CREATE INDEX idx_parking_lots_price ON parking_lots (price_per_hour);
|
||||
CREATE INDEX idx_parking_lots_availability ON parking_lots (available_spots, is_active);
|
||||
CREATE INDEX idx_parking_lots_rating ON parking_lots (average_rating DESC);
|
||||
|
||||
-- Composite index for common queries
|
||||
CREATE INDEX idx_parking_lots_active_location ON parking_lots (is_active, latitude, longitude);
|
||||
```
|
||||
|
||||
### 4. Parking Spots Table
|
||||
|
||||
```sql
|
||||
CREATE TYPE spot_type AS ENUM ('regular', 'disabled', 'electric', 'compact', 'motorcycle');
|
||||
|
||||
CREATE TABLE parking_spots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
parking_lot_id UUID REFERENCES parking_lots(id) ON DELETE CASCADE,
|
||||
|
||||
-- Spot identification
|
||||
spot_number VARCHAR(20) NOT NULL,
|
||||
floor_level INTEGER DEFAULT 0,
|
||||
section VARCHAR(10),
|
||||
|
||||
-- Spot characteristics
|
||||
type spot_type DEFAULT 'regular',
|
||||
size_category VARCHAR(20) DEFAULT 'standard', -- compact, standard, large
|
||||
|
||||
-- Status
|
||||
is_occupied BOOLEAN DEFAULT FALSE,
|
||||
is_reserved BOOLEAN DEFAULT FALSE,
|
||||
is_maintenance BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Timestamps
|
||||
last_updated TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
occupied_since TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Constraints
|
||||
UNIQUE(parking_lot_id, spot_number),
|
||||
CONSTRAINT valid_floor CHECK (floor_level BETWEEN -10 AND 50)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_parking_spots_lot ON parking_spots (parking_lot_id);
|
||||
CREATE INDEX idx_parking_spots_status ON parking_spots (is_occupied, is_reserved, is_maintenance);
|
||||
CREATE INDEX idx_parking_spots_type ON parking_spots (type);
|
||||
CREATE INDEX idx_parking_spots_availability ON parking_spots (parking_lot_id, is_occupied, is_reserved, is_maintenance);
|
||||
```
|
||||
|
||||
### 5. Reservations Table
|
||||
|
||||
```sql
|
||||
CREATE TYPE reservation_status AS ENUM (
|
||||
'pending',
|
||||
'confirmed',
|
||||
'active',
|
||||
'completed',
|
||||
'cancelled',
|
||||
'no_show',
|
||||
'expired'
|
||||
);
|
||||
|
||||
CREATE TABLE reservations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
parking_spot_id UUID REFERENCES parking_spots(id) ON DELETE CASCADE,
|
||||
|
||||
-- Timing
|
||||
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
end_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
||||
actual_start_time TIMESTAMP WITH TIME ZONE,
|
||||
actual_end_time TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Pricing
|
||||
base_cost DECIMAL(10,2) NOT NULL,
|
||||
discount_amount DECIMAL(10,2) DEFAULT 0,
|
||||
tax_amount DECIMAL(10,2) DEFAULT 0,
|
||||
total_cost DECIMAL(10,2) NOT NULL,
|
||||
currency CHAR(3) DEFAULT 'USD',
|
||||
|
||||
-- Vehicle information
|
||||
vehicle_info JSONB DEFAULT '{}',
|
||||
|
||||
-- Status and notes
|
||||
status reservation_status DEFAULT 'pending',
|
||||
special_requests TEXT,
|
||||
cancellation_reason TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
confirmation_code VARCHAR(10) UNIQUE,
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT valid_duration CHECK (end_time > start_time),
|
||||
CONSTRAINT valid_costs CHECK (
|
||||
base_cost >= 0 AND
|
||||
discount_amount >= 0 AND
|
||||
tax_amount >= 0 AND
|
||||
total_cost >= 0
|
||||
)
|
||||
);
|
||||
|
||||
-- Generate confirmation code
|
||||
CREATE OR REPLACE FUNCTION generate_confirmation_code()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
IF NEW.confirmation_code IS NULL THEN
|
||||
NEW.confirmation_code := upper(substring(md5(random()::text) from 1 for 8));
|
||||
END IF;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER set_confirmation_code
|
||||
BEFORE INSERT ON reservations
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION generate_confirmation_code();
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_reservations_user ON reservations (user_id);
|
||||
CREATE INDEX idx_reservations_spot ON reservations (parking_spot_id);
|
||||
CREATE INDEX idx_reservations_status ON reservations (status);
|
||||
CREATE INDEX idx_reservations_time_range ON reservations (start_time, end_time);
|
||||
CREATE INDEX idx_reservations_confirmation ON reservations (confirmation_code);
|
||||
|
||||
-- Composite indexes for common queries
|
||||
CREATE INDEX idx_reservations_user_status ON reservations (user_id, status);
|
||||
CREATE INDEX idx_reservations_spot_time ON reservations (parking_spot_id, start_time, end_time);
|
||||
```
|
||||
|
||||
### 6. Payments Table
|
||||
|
||||
```sql
|
||||
CREATE TYPE payment_method AS ENUM ('credit_card', 'debit_card', 'digital_wallet', 'bank_transfer', 'cash');
|
||||
CREATE TYPE payment_status AS ENUM ('pending', 'processing', 'completed', 'failed', 'refunded', 'disputed');
|
||||
|
||||
CREATE TABLE payments (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
reservation_id UUID REFERENCES reservations(id) ON DELETE CASCADE,
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
|
||||
-- Payment details
|
||||
amount DECIMAL(10,2) NOT NULL,
|
||||
currency CHAR(3) DEFAULT 'USD',
|
||||
method payment_method NOT NULL,
|
||||
status payment_status DEFAULT 'pending',
|
||||
|
||||
-- External payment provider information
|
||||
provider_name VARCHAR(50), -- stripe, paypal, etc.
|
||||
provider_transaction_id VARCHAR(255),
|
||||
provider_fee DECIMAL(10,2) DEFAULT 0,
|
||||
|
||||
-- Payment metadata
|
||||
payment_date TIMESTAMP WITH TIME ZONE,
|
||||
processed_at TIMESTAMP WITH TIME ZONE,
|
||||
failure_reason TEXT,
|
||||
refund_amount DECIMAL(10,2) DEFAULT 0,
|
||||
refund_date TIMESTAMP WITH TIME ZONE,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT valid_amount CHECK (amount > 0),
|
||||
CONSTRAINT valid_refund CHECK (refund_amount >= 0 AND refund_amount <= amount)
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_payments_reservation ON payments (reservation_id);
|
||||
CREATE INDEX idx_payments_user ON payments (user_id);
|
||||
CREATE INDEX idx_payments_status ON payments (status);
|
||||
CREATE INDEX idx_payments_method ON payments (method);
|
||||
CREATE INDEX idx_payments_provider ON payments (provider_name, provider_transaction_id);
|
||||
CREATE INDEX idx_payments_date ON payments (payment_date);
|
||||
```
|
||||
|
||||
### 7. Reviews Table
|
||||
|
||||
```sql
|
||||
CREATE TABLE reviews (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
parking_lot_id UUID REFERENCES parking_lots(id) ON DELETE CASCADE,
|
||||
reservation_id UUID REFERENCES reservations(id) ON DELETE SET NULL,
|
||||
|
||||
-- Review content
|
||||
rating INTEGER NOT NULL,
|
||||
title VARCHAR(255),
|
||||
comment TEXT,
|
||||
|
||||
-- Review metadata
|
||||
is_verified BOOLEAN DEFAULT FALSE, -- verified if linked to actual reservation
|
||||
is_flagged BOOLEAN DEFAULT FALSE,
|
||||
admin_response TEXT,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
-- Constraints
|
||||
CONSTRAINT valid_rating CHECK (rating BETWEEN 1 AND 5),
|
||||
UNIQUE(user_id, parking_lot_id) -- One review per user per parking lot
|
||||
);
|
||||
|
||||
-- Indexes
|
||||
CREATE INDEX idx_reviews_parking_lot ON reviews (parking_lot_id);
|
||||
CREATE INDEX idx_reviews_user ON reviews (user_id);
|
||||
CREATE INDEX idx_reviews_rating ON reviews (rating);
|
||||
CREATE INDEX idx_reviews_verified ON reviews (is_verified);
|
||||
CREATE INDEX idx_reviews_created_at ON reviews (created_at);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Indexes & Performance
|
||||
|
||||
### 1. Spatial Indexes for Location Queries
|
||||
|
||||
```sql
|
||||
-- Enable PostGIS extension for advanced spatial operations
|
||||
CREATE EXTENSION IF NOT EXISTS postgis;
|
||||
|
||||
-- Convert existing lat/lng to geometry for better performance
|
||||
ALTER TABLE parking_lots ADD COLUMN geom GEOMETRY(POINT, 4326);
|
||||
|
||||
-- Populate geometry column
|
||||
UPDATE parking_lots SET geom = ST_SetSRID(ST_MakePoint(longitude, latitude), 4326);
|
||||
|
||||
-- Create spatial index
|
||||
CREATE INDEX idx_parking_lots_geom ON parking_lots USING GIST (geom);
|
||||
|
||||
-- Function for distance-based queries
|
||||
CREATE OR REPLACE FUNCTION find_nearby_parking(
|
||||
user_lat DECIMAL,
|
||||
user_lng DECIMAL,
|
||||
radius_meters INTEGER DEFAULT 5000
|
||||
) RETURNS TABLE(
|
||||
id UUID,
|
||||
name VARCHAR,
|
||||
distance_meters DECIMAL
|
||||
) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
SELECT
|
||||
pl.id,
|
||||
pl.name,
|
||||
ST_Distance(
|
||||
ST_SetSRID(ST_MakePoint(user_lng, user_lat), 4326)::geography,
|
||||
pl.geom::geography
|
||||
) as distance_meters
|
||||
FROM parking_lots pl
|
||||
WHERE pl.is_active = TRUE
|
||||
AND ST_DWithin(
|
||||
ST_SetSRID(ST_MakePoint(user_lng, user_lat), 4326)::geography,
|
||||
pl.geom::geography,
|
||||
radius_meters
|
||||
)
|
||||
ORDER BY distance_meters;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
```
|
||||
|
||||
### 2. Partitioning Strategy
|
||||
|
||||
```sql
|
||||
-- Partition reservations by month for better performance
|
||||
CREATE TABLE reservations_partitioned (
|
||||
LIKE reservations INCLUDING ALL
|
||||
) PARTITION BY RANGE (start_time);
|
||||
|
||||
-- Create partitions for current and future months
|
||||
CREATE TABLE reservations_2024_08 PARTITION OF reservations_partitioned
|
||||
FOR VALUES FROM ('2024-08-01') TO ('2024-09-01');
|
||||
|
||||
CREATE TABLE reservations_2024_09 PARTITION OF reservations_partitioned
|
||||
FOR VALUES FROM ('2024-09-01') TO ('2024-10-01');
|
||||
|
||||
-- Automated partition creation function
|
||||
CREATE OR REPLACE FUNCTION create_monthly_partition()
|
||||
RETURNS void AS $$
|
||||
DECLARE
|
||||
start_date DATE;
|
||||
end_date DATE;
|
||||
table_name TEXT;
|
||||
BEGIN
|
||||
start_date := DATE_TRUNC('month', CURRENT_DATE + INTERVAL '1 month');
|
||||
end_date := start_date + INTERVAL '1 month';
|
||||
table_name := 'reservations_' || TO_CHAR(start_date, 'YYYY_MM');
|
||||
|
||||
EXECUTE FORMAT(
|
||||
'CREATE TABLE %I PARTITION OF reservations_partitioned
|
||||
FOR VALUES FROM (%L) TO (%L)',
|
||||
table_name, start_date, end_date
|
||||
);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Schedule monthly partition creation
|
||||
SELECT cron.schedule('create-partition', '0 0 1 * *', 'SELECT create_monthly_partition();');
|
||||
```
|
||||
|
||||
### 3. Performance Monitoring Views
|
||||
|
||||
```sql
|
||||
-- View for monitoring table sizes
|
||||
CREATE VIEW table_sizes AS
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
attname,
|
||||
n_distinct,
|
||||
correlation,
|
||||
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size
|
||||
FROM pg_stats
|
||||
WHERE schemaname = 'public'
|
||||
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;
|
||||
|
||||
-- View for monitoring index usage
|
||||
CREATE VIEW index_usage AS
|
||||
SELECT
|
||||
schemaname,
|
||||
tablename,
|
||||
attname,
|
||||
n_distinct,
|
||||
correlation
|
||||
FROM pg_stats
|
||||
WHERE schemaname = 'public';
|
||||
|
||||
-- View for monitoring slow queries
|
||||
CREATE VIEW slow_queries AS
|
||||
SELECT
|
||||
query,
|
||||
calls,
|
||||
total_time,
|
||||
mean_time,
|
||||
rows
|
||||
FROM pg_stat_statements
|
||||
WHERE mean_time > 100
|
||||
ORDER BY mean_time DESC;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Data Migration Strategy
|
||||
|
||||
### 1. Migration Scripts Structure
|
||||
|
||||
```sql
|
||||
-- Migration: 001_initial_schema.sql
|
||||
-- Description: Create initial database schema
|
||||
-- Date: 2024-08-03
|
||||
-- Author: System
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Create enums
|
||||
CREATE TYPE user_role AS ENUM ('customer', 'operator', 'admin');
|
||||
CREATE TYPE spot_type AS ENUM ('regular', 'disabled', 'electric', 'compact', 'motorcycle');
|
||||
-- ... rest of schema creation
|
||||
|
||||
-- Create migration tracking table
|
||||
CREATE TABLE IF NOT EXISTS schema_migrations (
|
||||
version VARCHAR(255) PRIMARY KEY,
|
||||
applied_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
INSERT INTO schema_migrations (version) VALUES ('001_initial_schema');
|
||||
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
### 2. Data Seeding
|
||||
|
||||
```sql
|
||||
-- Seed: 001_default_data.sql
|
||||
-- Description: Insert default operational data
|
||||
-- Date: 2024-08-03
|
||||
|
||||
BEGIN;
|
||||
|
||||
-- Insert default operator
|
||||
INSERT INTO operators (id, company_name, contact_email, contact_phone, is_active)
|
||||
VALUES (
|
||||
'b123b123-b123-b123-b123-b123b123b123',
|
||||
'City Parking Management',
|
||||
'admin@cityparking.com',
|
||||
'+1234567890',
|
||||
TRUE
|
||||
);
|
||||
|
||||
-- Insert sample parking lots
|
||||
INSERT INTO parking_lots (
|
||||
id, operator_id, name, address, latitude, longitude,
|
||||
total_spots, available_spots, price_per_hour, amenities
|
||||
) VALUES
|
||||
(
|
||||
'a123a123-a123-a123-a123-a123a123a123',
|
||||
'b123b123-b123-b123-b123-b123b123b123',
|
||||
'Downtown Parking Garage',
|
||||
'123 Main St, Downtown',
|
||||
40.7128,
|
||||
-74.0060,
|
||||
200,
|
||||
150,
|
||||
5.00,
|
||||
ARRAY['covered', 'security', 'electric_charging']
|
||||
);
|
||||
|
||||
COMMIT;
|
||||
```
|
||||
|
||||
### 3. Backup Strategy
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# backup_database.sh
|
||||
# Automated database backup script
|
||||
|
||||
DB_NAME="smart_parking"
|
||||
BACKUP_DIR="/backups/postgresql"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Create full backup
|
||||
pg_dump -h localhost -U postgres -d $DB_NAME \
|
||||
--verbose --format=custom \
|
||||
--file="$BACKUP_DIR/full_backup_$DATE.backup"
|
||||
|
||||
# Create schema-only backup
|
||||
pg_dump -h localhost -U postgres -d $DB_NAME \
|
||||
--schema-only --verbose \
|
||||
--file="$BACKUP_DIR/schema_backup_$DATE.sql"
|
||||
|
||||
# Cleanup old backups (keep last 30 days)
|
||||
find $BACKUP_DIR -name "*.backup" -mtime +30 -delete
|
||||
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Scaling Considerations
|
||||
|
||||
### 1. Read Replicas Configuration
|
||||
|
||||
```sql
|
||||
-- Master database configuration
|
||||
-- postgresql.conf
|
||||
wal_level = replica
|
||||
max_wal_senders = 3
|
||||
wal_keep_segments = 64
|
||||
hot_standby = on
|
||||
|
||||
-- Replica database queries
|
||||
-- Route read-only queries to replicas
|
||||
CREATE OR REPLACE FUNCTION is_read_only_query(query_text TEXT)
|
||||
RETURNS BOOLEAN AS $$
|
||||
BEGIN
|
||||
RETURN query_text ~* '^(SELECT|WITH)' AND
|
||||
query_text !~* '(FOR UPDATE|FOR SHARE)';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
```
|
||||
|
||||
### 2. Connection Pooling
|
||||
|
||||
```javascript
|
||||
// Database connection pool configuration
|
||||
const poolConfig = {
|
||||
host: process.env.DB_HOST,
|
||||
port: process.env.DB_PORT,
|
||||
database: process.env.DB_NAME,
|
||||
user: process.env.DB_USER,
|
||||
password: process.env.DB_PASSWORD,
|
||||
|
||||
// Pool configuration
|
||||
min: 5, // Minimum connections
|
||||
max: 50, // Maximum connections
|
||||
idle: 10000, // Idle timeout (10 seconds)
|
||||
acquire: 60000, // Acquire timeout (60 seconds)
|
||||
evict: 1000, // Eviction run interval (1 second)
|
||||
|
||||
// Connection validation
|
||||
validate: true,
|
||||
validateTimeout: 3000,
|
||||
|
||||
// Logging
|
||||
logging: (sql, timing) => {
|
||||
if (timing > 1000) {
|
||||
console.warn(`Slow query detected: ${timing}ms - ${sql}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Caching Strategy
|
||||
|
||||
```sql
|
||||
-- Materialized views for expensive aggregations
|
||||
CREATE MATERIALIZED VIEW parking_lot_stats AS
|
||||
SELECT
|
||||
pl.id,
|
||||
pl.name,
|
||||
pl.total_spots,
|
||||
pl.available_spots,
|
||||
ROUND(AVG(r.rating), 2) as avg_rating,
|
||||
COUNT(r.id) as total_reviews,
|
||||
COUNT(res.id) as total_reservations
|
||||
FROM parking_lots pl
|
||||
LEFT JOIN reviews r ON pl.id = r.parking_lot_id
|
||||
LEFT JOIN reservations res ON pl.id = res.parking_spot_id
|
||||
WHERE pl.is_active = TRUE
|
||||
GROUP BY pl.id, pl.name, pl.total_spots, pl.available_spots;
|
||||
|
||||
-- Refresh materialized view regularly
|
||||
CREATE OR REPLACE FUNCTION refresh_parking_stats()
|
||||
RETURNS void AS $$
|
||||
BEGIN
|
||||
REFRESH MATERIALIZED VIEW CONCURRENTLY parking_lot_stats;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
-- Schedule refresh every hour
|
||||
SELECT cron.schedule('refresh-stats', '0 * * * *', 'SELECT refresh_parking_stats();');
|
||||
```
|
||||
|
||||
### 4. Database Monitoring
|
||||
|
||||
```sql
|
||||
-- Create monitoring functions
|
||||
CREATE OR REPLACE FUNCTION database_health_check()
|
||||
RETURNS TABLE(
|
||||
metric VARCHAR,
|
||||
value DECIMAL,
|
||||
status VARCHAR
|
||||
) AS $$
|
||||
BEGIN
|
||||
RETURN QUERY
|
||||
WITH metrics AS (
|
||||
SELECT 'active_connections' as metric,
|
||||
COUNT(*)::DECIMAL as value,
|
||||
CASE WHEN COUNT(*) > 80 THEN 'WARNING' ELSE 'OK' END as status
|
||||
FROM pg_stat_activity
|
||||
WHERE state = 'active'
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT 'cache_hit_ratio' as metric,
|
||||
ROUND(
|
||||
100.0 * sum(blks_hit) / (sum(blks_hit) + sum(blks_read)), 2
|
||||
) as value,
|
||||
CASE WHEN 100.0 * sum(blks_hit) / (sum(blks_hit) + sum(blks_read)) < 95
|
||||
THEN 'WARNING' ELSE 'OK' END as status
|
||||
FROM pg_stat_database
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT 'table_bloat' as metric,
|
||||
pg_size_pretty(pg_database_size(current_database()))::DECIMAL as value,
|
||||
'INFO' as status
|
||||
)
|
||||
SELECT * FROM metrics;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: August 3, 2025*
|
||||
*Version: 1.0.0*
|
||||
451
Documents/README.md
Normal file
451
Documents/README.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# 📚 Smart Parking Finder - Complete Documentation Index
|
||||
|
||||
## 🏗️ Project Overview
|
||||
|
||||
**Smart Parking Finder** is a comprehensive real-time parking management system that revolutionizes urban parking through intelligent location-based services, interactive mapping, and seamless user experience.
|
||||
|
||||
### 🎯 Project Vision
|
||||
Transform urban parking from a frustrating experience into a streamlined, intelligent process that saves time, reduces traffic congestion, and optimizes parking resource utilization.
|
||||
|
||||
---
|
||||
|
||||
## 📖 Documentation Structure
|
||||
|
||||
### 📁 Core Documentation
|
||||
|
||||
| Document | Description | Purpose |
|
||||
|----------|-------------|---------|
|
||||
| **[LOCAL_DEPLOYMENT_GUIDE.md](./LOCAL_DEPLOYMENT_GUIDE.md)** | Complete deployment instructions | Get the system running locally |
|
||||
| **[SYSTEM_ARCHITECTURE.md](./SYSTEM_ARCHITECTURE.md)** | System design & architecture patterns | Understand how the system works |
|
||||
| **[API_SCHEMA.md](./API_SCHEMA.md)** | Complete API documentation & schemas | API integration & development |
|
||||
| **[DATABASE_DESIGN.md](./DATABASE_DESIGN.md)** | Database schema & design patterns | Database development & optimization |
|
||||
|
||||
### 📁 Technical Documentation
|
||||
|
||||
| Document | Description | Status |
|
||||
|----------|-------------|--------|
|
||||
| **DEVELOPMENT.md** | Development workflow & standards | ✅ Available |
|
||||
| **DEPLOYMENT.md** | Production deployment guide | ✅ Available |
|
||||
| **TECHNICAL_SPECIFICATION.md** | Detailed technical specifications | ✅ Available |
|
||||
| **PERFORMANCE_OPTIMIZATION_REPORT.md** | Performance analysis & optimizations | ✅ Available |
|
||||
| **MAPVIEW_VERSIONS.md** | MapView component evolution | ✅ Available |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Technology Stack Summary
|
||||
|
||||
### Frontend Architecture
|
||||
```json
|
||||
{
|
||||
"framework": "Next.js 14 (App Router)",
|
||||
"runtime": "React 18",
|
||||
"language": "TypeScript 5.x",
|
||||
"styling": "Tailwind CSS 3.x",
|
||||
"mapping": "React Leaflet + OpenStreetMap",
|
||||
"state_management": "React Query (TanStack Query)",
|
||||
"forms": "React Hook Form",
|
||||
"ui_components": "Custom + Shadcn/ui",
|
||||
"testing": "Jest + React Testing Library"
|
||||
}
|
||||
```
|
||||
|
||||
### Backend Architecture
|
||||
```json
|
||||
{
|
||||
"framework": "NestJS 10",
|
||||
"runtime": "Node.js 18+",
|
||||
"language": "TypeScript 5.x",
|
||||
"database": "PostgreSQL 15 + PostGIS",
|
||||
"cache": "Redis 7",
|
||||
"orm": "TypeORM",
|
||||
"authentication": "JWT + Passport",
|
||||
"validation": "Class Validator",
|
||||
"documentation": "Swagger/OpenAPI",
|
||||
"testing": "Jest + Supertest"
|
||||
}
|
||||
```
|
||||
|
||||
### Infrastructure & DevOps
|
||||
```json
|
||||
{
|
||||
"containerization": "Docker + Docker Compose",
|
||||
"routing_engine": "Valhalla Routing Engine",
|
||||
"mapping_data": "OpenStreetMap",
|
||||
"process_management": "PM2",
|
||||
"monitoring": "Health Check Endpoints",
|
||||
"logging": "Winston Logger"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start Guide
|
||||
|
||||
### 1. Prerequisites Check
|
||||
```bash
|
||||
# Verify Node.js version
|
||||
node --version # Should be 18+
|
||||
|
||||
# Verify npm version
|
||||
npm --version # Should be 8+
|
||||
|
||||
# Verify Docker (optional)
|
||||
docker --version
|
||||
```
|
||||
|
||||
### 2. Fastest Setup (Frontend Only)
|
||||
```bash
|
||||
# Clone and start frontend
|
||||
git clone <repository>
|
||||
cd Website_Demo_App
|
||||
./launch.sh
|
||||
# Choose option 2: Quick demo
|
||||
```
|
||||
|
||||
### 3. Full Development Setup
|
||||
```bash
|
||||
# Start complete development environment
|
||||
./launch.sh
|
||||
# Choose option 3: Full development
|
||||
```
|
||||
|
||||
### 4. Production-like Setup
|
||||
```bash
|
||||
# Start with Docker (includes database)
|
||||
./scripts/docker-dev.sh
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🏛️ System Architecture Overview
|
||||
|
||||
### High-Level Architecture
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Client Layer │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Next.js Frontend (React 18 + TypeScript + Tailwind CSS) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────┴─────────┐
|
||||
│ API Gateway │
|
||||
│ (NestJS Router) │
|
||||
└─────────┬─────────┘
|
||||
│
|
||||
┌─────────────────────┼─────────────────────┐
|
||||
│ │ │
|
||||
┌───────▼───────┐ ┌─────────▼─────────┐ ┌───────▼───────┐
|
||||
│ Auth Service │ │ Parking Service │ │Routing Service│
|
||||
│ (JWT) │ │ (CRUD + Search) │ │ (Valhalla) │
|
||||
└───────────────┘ └───────────────────┘ └───────────────┘
|
||||
│ │ │
|
||||
└─────────────────────┼─────────────────────┘
|
||||
│
|
||||
┌─────────▼─────────┐
|
||||
│ Data Layer │
|
||||
│ PostgreSQL + Redis│
|
||||
└───────────────────┘
|
||||
```
|
||||
|
||||
### Core Features
|
||||
- 🗺️ **Interactive Mapping**: Real-time OpenStreetMap with custom markers
|
||||
- 🔍 **Smart Search**: Geolocation-based parking spot discovery
|
||||
- 🧭 **Route Optimization**: Multi-modal routing with Valhalla engine
|
||||
- 📱 **Responsive Design**: Mobile-first, progressive web app
|
||||
- ⚡ **Real-time Updates**: WebSocket-based live availability
|
||||
- 🔐 **Secure Authentication**: JWT-based user management
|
||||
- 💳 **Payment Integration**: Ready for payment processor integration
|
||||
|
||||
---
|
||||
|
||||
## 📊 Data Models & Schema
|
||||
|
||||
### Core Entities
|
||||
|
||||
#### 1. Users & Authentication
|
||||
```typescript
|
||||
interface User {
|
||||
id: string;
|
||||
email: string;
|
||||
fullName: string;
|
||||
phone?: string;
|
||||
role: 'customer' | 'operator' | 'admin';
|
||||
preferences: UserPreferences;
|
||||
metadata: UserMetadata;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Parking Infrastructure
|
||||
```typescript
|
||||
interface ParkingLot {
|
||||
id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
coordinates: GeoCoordinates;
|
||||
availability: AvailabilityInfo;
|
||||
pricing: PricingInfo;
|
||||
operatingHours: OperatingHours;
|
||||
amenities: string[];
|
||||
metadata: ParkingMetadata;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Reservations & Transactions
|
||||
```typescript
|
||||
interface Reservation {
|
||||
id: string;
|
||||
userId: string;
|
||||
parkingSpotId: string;
|
||||
timeSlot: TimeSlot;
|
||||
pricing: ReservationPricing;
|
||||
status: ReservationStatus;
|
||||
metadata: ReservationMetadata;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 API Reference
|
||||
|
||||
### Authentication Endpoints
|
||||
- `POST /api/auth/login` - User authentication
|
||||
- `POST /api/auth/register` - User registration
|
||||
- `POST /api/auth/refresh` - Token refresh
|
||||
- `GET /api/auth/profile` - User profile
|
||||
|
||||
### Parking Endpoints
|
||||
- `GET /api/parking/search` - Search nearby parking
|
||||
- `GET /api/parking/:id` - Get parking details
|
||||
- `POST /api/parking/:id/reserve` - Create reservation
|
||||
- `GET /api/parking/reservations` - User reservations
|
||||
|
||||
### Routing Endpoints
|
||||
- `POST /api/routing/calculate` - Calculate route
|
||||
- `GET /api/routing/modes` - Available transport modes
|
||||
|
||||
### Health & Monitoring
|
||||
- `GET /api/health` - System health check
|
||||
- `GET /api/metrics` - System metrics
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Database Schema Summary
|
||||
|
||||
### Primary Tables
|
||||
1. **users** - User accounts and profiles
|
||||
2. **operators** - Parking lot operators/managers
|
||||
3. **parking_lots** - Physical parking locations
|
||||
4. **parking_spots** - Individual parking spaces
|
||||
5. **reservations** - Booking records
|
||||
6. **payments** - Transaction records
|
||||
7. **reviews** - User feedback and ratings
|
||||
|
||||
### Key Relationships
|
||||
- Users can make multiple reservations
|
||||
- Parking lots contain multiple spots
|
||||
- Reservations link users to specific spots
|
||||
- Payments are triggered by reservations
|
||||
- Reviews are tied to parking lots and users
|
||||
|
||||
### Performance Optimizations
|
||||
- Spatial indexes for location-based queries
|
||||
- Partitioning for time-series data (reservations)
|
||||
- Materialized views for expensive aggregations
|
||||
- Connection pooling for database efficiency
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Development Workflow
|
||||
|
||||
### Environment Setup
|
||||
1. **Development**: `./scripts/frontend-only.sh` (Quick demo)
|
||||
2. **Full Stack**: `./scripts/full-dev.sh` (Frontend + Backend)
|
||||
3. **Production-like**: `./scripts/docker-dev.sh` (Docker environment)
|
||||
4. **Interactive**: `./launch.sh` (Menu with all options)
|
||||
|
||||
### Code Organization
|
||||
```
|
||||
frontend/
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router pages
|
||||
│ ├── components/ # React components
|
||||
│ ├── hooks/ # Custom React hooks
|
||||
│ ├── services/ # API integration
|
||||
│ ├── types/ # TypeScript type definitions
|
||||
│ └── utils/ # Utility functions
|
||||
backend/
|
||||
├── src/
|
||||
│ ├── modules/ # Feature modules (auth, parking, routing)
|
||||
│ ├── config/ # Configuration files
|
||||
│ └── database/ # Database seeds and migrations
|
||||
```
|
||||
|
||||
### Development Standards
|
||||
- **TypeScript**: Strict mode enabled
|
||||
- **ESLint**: Code quality enforcement
|
||||
- **Prettier**: Code formatting
|
||||
- **Jest**: Unit and integration testing
|
||||
- **Conventional Commits**: Commit message standards
|
||||
|
||||
---
|
||||
|
||||
## 📈 Performance & Optimization
|
||||
|
||||
### Frontend Optimizations
|
||||
- **Code Splitting**: Route-based and component-based
|
||||
- **Image Optimization**: Next.js Image component
|
||||
- **Caching**: React Query for API state management
|
||||
- **Lazy Loading**: Components and routes
|
||||
- **Bundle Analysis**: Webpack bundle analyzer
|
||||
|
||||
### Backend Optimizations
|
||||
- **Database Indexing**: Spatial and composite indexes
|
||||
- **Caching Strategy**: Redis for frequently accessed data
|
||||
- **Connection Pooling**: PostgreSQL connection optimization
|
||||
- **Query Optimization**: Efficient database queries
|
||||
- **Rate Limiting**: API protection and resource management
|
||||
|
||||
### Infrastructure Optimizations
|
||||
- **Docker**: Containerized deployment
|
||||
- **Health Checks**: Monitoring and alerting
|
||||
- **Logging**: Structured logging with Winston
|
||||
- **Process Management**: PM2 for production
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security Considerations
|
||||
|
||||
### Authentication & Authorization
|
||||
- **JWT Tokens**: Secure token-based authentication
|
||||
- **Role-based Access**: Customer, operator, admin roles
|
||||
- **Password Security**: Bcrypt hashing
|
||||
- **Session Management**: Refresh token rotation
|
||||
|
||||
### Data Protection
|
||||
- **Input Validation**: DTO validation with class-validator
|
||||
- **SQL Injection Prevention**: TypeORM parameterized queries
|
||||
- **CORS Configuration**: Restricted origin access
|
||||
- **Rate Limiting**: API abuse prevention
|
||||
- **HTTPS**: TLS encryption (production)
|
||||
|
||||
### Privacy & Compliance
|
||||
- **Data Minimization**: Collect only necessary data
|
||||
- **User Consent**: Clear privacy policies
|
||||
- **Data Retention**: Automated cleanup of old data
|
||||
- **Audit Logging**: Security event tracking
|
||||
|
||||
---
|
||||
|
||||
## 🌐 Deployment Options
|
||||
|
||||
### Local Development
|
||||
```bash
|
||||
# Quick frontend demo
|
||||
./scripts/frontend-only.sh
|
||||
|
||||
# Full development stack
|
||||
./scripts/full-dev.sh
|
||||
|
||||
# Docker environment
|
||||
./scripts/docker-dev.sh
|
||||
|
||||
# Interactive launcher
|
||||
./launch.sh
|
||||
```
|
||||
|
||||
### Production Deployment
|
||||
```bash
|
||||
# Docker production setup
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
|
||||
# Traditional deployment
|
||||
npm run build && npm run start
|
||||
```
|
||||
|
||||
### Cloud Deployment
|
||||
- **Vercel**: Frontend deployment (recommended)
|
||||
- **Railway/Heroku**: Full-stack deployment
|
||||
- **AWS/GCP**: Enterprise deployment
|
||||
- **Docker**: Containerized deployment
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
1. **Port conflicts**: Use `lsof -ti:3000` to check port usage
|
||||
2. **Node version**: Ensure Node.js 18+ is installed
|
||||
3. **Docker issues**: Verify Docker Desktop is running
|
||||
4. **Database connection**: Check PostgreSQL service status
|
||||
|
||||
### Debug Mode
|
||||
```bash
|
||||
# Frontend debug mode
|
||||
cd frontend && npm run dev -- --debug
|
||||
|
||||
# Backend debug mode
|
||||
cd backend && npm run start:debug
|
||||
```
|
||||
|
||||
### Logs Location
|
||||
- **Frontend**: Browser console (F12)
|
||||
- **Backend**: Terminal output and log files
|
||||
- **Database**: PostgreSQL logs
|
||||
- **Docker**: `docker-compose logs`
|
||||
|
||||
---
|
||||
|
||||
## 📞 Support & Resources
|
||||
|
||||
### Documentation Links
|
||||
- [Local Deployment Guide](./LOCAL_DEPLOYMENT_GUIDE.md)
|
||||
- [System Architecture](./SYSTEM_ARCHITECTURE.md)
|
||||
- [API Documentation](./API_SCHEMA.md)
|
||||
- [Database Design](./DATABASE_DESIGN.md)
|
||||
|
||||
### Development Resources
|
||||
- **Next.js Documentation**: https://nextjs.org/docs
|
||||
- **NestJS Documentation**: https://docs.nestjs.com
|
||||
- **React Leaflet**: https://react-leaflet.js.org
|
||||
- **TypeORM**: https://typeorm.io
|
||||
- **PostgreSQL**: https://www.postgresql.org/docs
|
||||
|
||||
### Community & Support
|
||||
- GitHub Issues for bug reports
|
||||
- Development team for feature requests
|
||||
- Stack Overflow for technical questions
|
||||
- Documentation updates via pull requests
|
||||
|
||||
---
|
||||
|
||||
## 🗺️ Roadmap & Future Enhancements
|
||||
|
||||
### Phase 1 (Current) - Core Features ✅
|
||||
- Interactive mapping and search
|
||||
- Basic reservation system
|
||||
- User authentication
|
||||
- Real-time availability
|
||||
|
||||
### Phase 2 - Enhanced Features 🚧
|
||||
- Payment integration
|
||||
- Mobile applications
|
||||
- Advanced analytics
|
||||
- Multi-language support
|
||||
|
||||
### Phase 3 - AI & IoT Integration 📋
|
||||
- Predictive availability
|
||||
- Smart parking sensors
|
||||
- Machine learning optimization
|
||||
- Advanced routing algorithms
|
||||
|
||||
### Phase 4 - Enterprise Features 📋
|
||||
- Multi-tenant architecture
|
||||
- Advanced reporting
|
||||
- API marketplace
|
||||
- White-label solutions
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: August 3, 2025*
|
||||
*Version: 1.0.0*
|
||||
*Project Status: Active Development*
|
||||
611
Documents/SYSTEM_ARCHITECTURE.md
Normal file
611
Documents/SYSTEM_ARCHITECTURE.md
Normal file
@@ -0,0 +1,611 @@
|
||||
# 🏗️ Smart Parking Finder - System Architecture Documentation
|
||||
|
||||
## 📋 Table of Contents
|
||||
1. [System Overview](#system-overview)
|
||||
2. [Architecture Patterns](#architecture-patterns)
|
||||
3. [Technology Stack](#technology-stack)
|
||||
4. [Data Structure & Schema](#data-structure--schema)
|
||||
5. [System Design](#system-design)
|
||||
6. [API Documentation](#api-documentation)
|
||||
7. [Database Design](#database-design)
|
||||
8. [Security & Performance](#security--performance)
|
||||
|
||||
---
|
||||
|
||||
## 🎯 System Overview
|
||||
|
||||
### Project Description
|
||||
Smart Parking Finder is a real-time parking management system that helps users find available parking spots in urban areas. The system provides interactive mapping, route optimization, and real-time availability tracking.
|
||||
|
||||
### Core Features
|
||||
- 🗺️ Interactive map with OpenStreetMap integration
|
||||
- 🔍 Real-time parking spot search
|
||||
- 🧭 GPS-based navigation and routing
|
||||
- 📱 Responsive web application
|
||||
- 🔄 Real-time data synchronization
|
||||
- 📊 Analytics and reporting
|
||||
|
||||
### System Goals
|
||||
- **Performance**: Sub-second response times for searches
|
||||
- **Scalability**: Support 10,000+ concurrent users
|
||||
- **Reliability**: 99.9% uptime availability
|
||||
- **Usability**: Intuitive interface for all user types
|
||||
|
||||
---
|
||||
|
||||
## 🏛️ Architecture Patterns
|
||||
|
||||
### 1. Microservices Architecture
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Client Layer │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Next.js Frontend (React 18 + TypeScript + Tailwind CSS) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
┌─────────┴─────────┐
|
||||
│ API Gateway │
|
||||
│ (NestJS Router) │
|
||||
└─────────┬─────────┘
|
||||
│
|
||||
┌─────────────────────┼─────────────────────┐
|
||||
│ │ │
|
||||
┌───────▼───────┐ ┌─────────▼─────────┐ ┌───────▼───────┐
|
||||
│ Auth Service │ │ Parking Service │ │Routing Service│
|
||||
│ (JWT) │ │ (CRUD + Search) │ │ (Valhalla) │
|
||||
└───────────────┘ └───────────────────┘ └───────────────┘
|
||||
│ │ │
|
||||
└─────────────────────┼─────────────────────┘
|
||||
│
|
||||
┌─────────▼─────────┐
|
||||
│ Data Layer │
|
||||
│ PostgreSQL + Redis│
|
||||
└───────────────────┘
|
||||
```
|
||||
|
||||
### 2. Layered Architecture
|
||||
- **Presentation Layer**: Next.js React Components
|
||||
- **Business Logic Layer**: NestJS Services & Controllers
|
||||
- **Data Access Layer**: TypeORM Repositories
|
||||
- **Database Layer**: PostgreSQL with Redis Cache
|
||||
|
||||
### 3. Event-Driven Architecture
|
||||
- Real-time updates using WebSocket connections
|
||||
- Event sourcing for parking availability changes
|
||||
- Message queuing for background tasks
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Technology Stack
|
||||
|
||||
### Frontend Stack
|
||||
```json
|
||||
{
|
||||
"framework": "Next.js 14",
|
||||
"runtime": "React 18",
|
||||
"language": "TypeScript 5.x",
|
||||
"styling": "Tailwind CSS 3.x",
|
||||
"mapping": "React Leaflet + OpenStreetMap",
|
||||
"state": "React Query (TanStack Query)",
|
||||
"forms": "React Hook Form",
|
||||
"testing": "Jest + React Testing Library"
|
||||
}
|
||||
```
|
||||
|
||||
### Backend Stack
|
||||
```json
|
||||
{
|
||||
"framework": "NestJS 10",
|
||||
"runtime": "Node.js 18+",
|
||||
"language": "TypeScript 5.x",
|
||||
"database": "PostgreSQL 15",
|
||||
"cache": "Redis 7",
|
||||
"orm": "TypeORM",
|
||||
"authentication": "JWT + Passport",
|
||||
"validation": "Class Validator",
|
||||
"documentation": "Swagger/OpenAPI",
|
||||
"testing": "Jest + Supertest"
|
||||
}
|
||||
```
|
||||
|
||||
### Infrastructure Stack
|
||||
```json
|
||||
{
|
||||
"containerization": "Docker + Docker Compose",
|
||||
"routing": "Valhalla Routing Engine",
|
||||
"mapping": "OpenStreetMap Data",
|
||||
"monitoring": "Health Check Endpoints",
|
||||
"logging": "Winston Logger",
|
||||
"process": "PM2 Process Manager"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 Data Structure & Schema
|
||||
|
||||
### 1. Database Schema
|
||||
|
||||
#### Users Table
|
||||
```sql
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
full_name VARCHAR(255) NOT NULL,
|
||||
phone VARCHAR(20),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT true,
|
||||
role user_role DEFAULT 'customer'
|
||||
);
|
||||
|
||||
CREATE TYPE user_role AS ENUM ('customer', 'operator', 'admin');
|
||||
```
|
||||
|
||||
#### Parking Lots Table
|
||||
```sql
|
||||
CREATE TABLE parking_lots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
latitude DECIMAL(10,8) NOT NULL,
|
||||
longitude DECIMAL(11,8) NOT NULL,
|
||||
total_spots INTEGER NOT NULL DEFAULT 0,
|
||||
available_spots INTEGER NOT NULL DEFAULT 0,
|
||||
price_per_hour DECIMAL(10,2) NOT NULL,
|
||||
operating_hours JSONB,
|
||||
amenities TEXT[],
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT true
|
||||
);
|
||||
|
||||
-- Spatial index for location-based queries
|
||||
CREATE INDEX idx_parking_lots_location ON parking_lots USING GIST (
|
||||
ll_to_earth(latitude, longitude)
|
||||
);
|
||||
```
|
||||
|
||||
#### Parking Spots Table
|
||||
```sql
|
||||
CREATE TABLE parking_spots (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
parking_lot_id UUID REFERENCES parking_lots(id) ON DELETE CASCADE,
|
||||
spot_number VARCHAR(20) NOT NULL,
|
||||
spot_type spot_type DEFAULT 'regular',
|
||||
is_occupied BOOLEAN DEFAULT false,
|
||||
is_reserved BOOLEAN DEFAULT false,
|
||||
last_updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(parking_lot_id, spot_number)
|
||||
);
|
||||
|
||||
CREATE TYPE spot_type AS ENUM ('regular', 'disabled', 'electric', 'compact');
|
||||
```
|
||||
|
||||
#### Reservations Table
|
||||
```sql
|
||||
CREATE TABLE reservations (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
|
||||
parking_spot_id UUID REFERENCES parking_spots(id) ON DELETE CASCADE,
|
||||
start_time TIMESTAMP NOT NULL,
|
||||
end_time TIMESTAMP NOT NULL,
|
||||
total_cost DECIMAL(10,2) NOT NULL,
|
||||
status reservation_status DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TYPE reservation_status AS ENUM ('pending', 'confirmed', 'active', 'completed', 'cancelled');
|
||||
```
|
||||
|
||||
### 2. API Data Models
|
||||
|
||||
#### Parking Lot Response Model
|
||||
```typescript
|
||||
interface ParkingLot {
|
||||
id: string;
|
||||
name: string;
|
||||
address: string;
|
||||
coordinates: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
availability: {
|
||||
totalSpots: number;
|
||||
availableSpots: number;
|
||||
occupancyRate: number;
|
||||
};
|
||||
pricing: {
|
||||
hourlyRate: number;
|
||||
currency: string;
|
||||
discounts?: Discount[];
|
||||
};
|
||||
operatingHours: {
|
||||
[day: string]: {
|
||||
open: string;
|
||||
close: string;
|
||||
is24Hours: boolean;
|
||||
};
|
||||
};
|
||||
amenities: string[];
|
||||
distance?: number;
|
||||
estimatedWalkTime?: number;
|
||||
metadata: {
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
isActive: boolean;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Search Request Model
|
||||
```typescript
|
||||
interface ParkingSearchRequest {
|
||||
location: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
};
|
||||
radius: number; // in meters
|
||||
filters?: {
|
||||
maxPrice?: number;
|
||||
amenities?: string[];
|
||||
spotTypes?: SpotType[];
|
||||
availableOnly?: boolean;
|
||||
};
|
||||
sorting?: {
|
||||
field: 'distance' | 'price' | 'availability';
|
||||
order: 'asc' | 'desc';
|
||||
};
|
||||
pagination?: {
|
||||
page: number;
|
||||
limit: number;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Route Response Model
|
||||
```typescript
|
||||
interface RouteResponse {
|
||||
route: {
|
||||
distance: number; // in meters
|
||||
duration: number; // in seconds
|
||||
coordinates: [number, number][]; // [lng, lat] pairs
|
||||
};
|
||||
instructions: RouteInstruction[];
|
||||
summary: {
|
||||
totalDistance: string;
|
||||
totalTime: string;
|
||||
estimatedCost: number;
|
||||
};
|
||||
}
|
||||
|
||||
interface RouteInstruction {
|
||||
text: string;
|
||||
distance: number;
|
||||
time: number;
|
||||
sign: number;
|
||||
interval: [number, number];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 System Design
|
||||
|
||||
### 1. Frontend Architecture
|
||||
|
||||
#### Component Hierarchy
|
||||
```
|
||||
App (layout.tsx)
|
||||
├── Header
|
||||
├── LocationDetector
|
||||
├── MapView
|
||||
│ ├── LeafletMap
|
||||
│ ├── ParkingMarkers
|
||||
│ ├── RouteLayer
|
||||
│ └── LocationMarker
|
||||
├── ParkingList
|
||||
│ ├── ParkingCard
|
||||
│ └── PaginationControls
|
||||
├── BookingModal
|
||||
├── TransportationSelector
|
||||
└── GPSSimulator (dev only)
|
||||
```
|
||||
|
||||
#### State Management
|
||||
```typescript
|
||||
// Global State Structure
|
||||
interface AppState {
|
||||
user: {
|
||||
profile: UserProfile | null;
|
||||
authentication: AuthState;
|
||||
preferences: UserPreferences;
|
||||
};
|
||||
location: {
|
||||
current: Coordinates | null;
|
||||
permissions: LocationPermission;
|
||||
tracking: boolean;
|
||||
};
|
||||
parking: {
|
||||
searchResults: ParkingLot[];
|
||||
selectedLot: ParkingLot | null;
|
||||
filters: SearchFilters;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
};
|
||||
routing: {
|
||||
currentRoute: RouteResponse | null;
|
||||
isCalculating: boolean;
|
||||
transportMode: TransportMode;
|
||||
};
|
||||
ui: {
|
||||
mapCenter: Coordinates;
|
||||
mapZoom: number;
|
||||
sidebarOpen: boolean;
|
||||
modalState: ModalState;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Backend Architecture
|
||||
|
||||
#### Service Layer Design
|
||||
```typescript
|
||||
// Parking Service Architecture
|
||||
@Injectable()
|
||||
export class ParkingService {
|
||||
constructor(
|
||||
private readonly parkingRepository: ParkingRepository,
|
||||
private readonly cacheService: CacheService,
|
||||
private readonly geoService: GeoService
|
||||
) {}
|
||||
|
||||
async findNearbyParking(searchDto: ParkingSearchDto): Promise<ParkingLot[]> {
|
||||
// 1. Check cache first
|
||||
const cacheKey = this.generateCacheKey(searchDto);
|
||||
const cached = await this.cacheService.get(cacheKey);
|
||||
if (cached) return cached;
|
||||
|
||||
// 2. Perform spatial query
|
||||
const results = await this.parkingRepository.findWithinRadius({
|
||||
latitude: searchDto.latitude,
|
||||
longitude: searchDto.longitude,
|
||||
radius: searchDto.radius
|
||||
});
|
||||
|
||||
// 3. Apply filters and sorting
|
||||
const filtered = this.applyFilters(results, searchDto.filters);
|
||||
const sorted = this.applySorting(filtered, searchDto.sorting);
|
||||
|
||||
// 4. Cache results
|
||||
await this.cacheService.set(cacheKey, sorted, 300); // 5 min cache
|
||||
|
||||
return sorted;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Repository Pattern
|
||||
```typescript
|
||||
@EntityRepository(ParkingLot)
|
||||
export class ParkingRepository extends Repository<ParkingLot> {
|
||||
async findWithinRadius(params: SpatialQueryParams): Promise<ParkingLot[]> {
|
||||
return this.createQueryBuilder('parking')
|
||||
.select()
|
||||
.addSelect(`
|
||||
(6371 * acos(
|
||||
cos(radians(:lat)) * cos(radians(latitude)) *
|
||||
cos(radians(longitude) - radians(:lng)) +
|
||||
sin(radians(:lat)) * sin(radians(latitude))
|
||||
)) AS distance
|
||||
`)
|
||||
.where(`
|
||||
(6371 * acos(
|
||||
cos(radians(:lat)) * cos(radians(latitude)) *
|
||||
cos(radians(longitude) - radians(:lng)) +
|
||||
sin(radians(:lat)) * sin(radians(latitude))
|
||||
)) <= :radius
|
||||
`)
|
||||
.andWhere('is_active = true')
|
||||
.setParameters({
|
||||
lat: params.latitude,
|
||||
lng: params.longitude,
|
||||
radius: params.radius / 1000 // Convert to km
|
||||
})
|
||||
.orderBy('distance', 'ASC')
|
||||
.getMany();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Real-time Updates
|
||||
|
||||
#### WebSocket Integration
|
||||
```typescript
|
||||
// WebSocket Gateway for real-time updates
|
||||
@WebSocketGateway({
|
||||
cors: { origin: '*' },
|
||||
transports: ['websocket', 'polling']
|
||||
})
|
||||
export class ParkingGateway implements OnGatewayConnection, OnGatewayDisconnect {
|
||||
@WebSocketServer() server: Server;
|
||||
|
||||
async handleConnection(client: Socket) {
|
||||
// Subscribe client to location-based updates
|
||||
const { latitude, longitude, radius } = client.handshake.query;
|
||||
const room = this.generateLocationRoom(latitude, longitude, radius);
|
||||
client.join(room);
|
||||
}
|
||||
|
||||
@SubscribeMessage('parkingUpdate')
|
||||
async handleParkingUpdate(client: Socket, data: ParkingUpdateDto) {
|
||||
// Broadcast to relevant clients
|
||||
const affectedRooms = this.getAffectedRooms(data.location);
|
||||
affectedRooms.forEach(room => {
|
||||
this.server.to(room).emit('parkingAvailabilityChanged', {
|
||||
parkingLotId: data.parkingLotId,
|
||||
availableSpots: data.availableSpots,
|
||||
timestamp: new Date().toISOString()
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔗 API Documentation
|
||||
|
||||
### Authentication Endpoints
|
||||
```typescript
|
||||
POST /api/auth/login
|
||||
POST /api/auth/register
|
||||
POST /api/auth/refresh
|
||||
DELETE /api/auth/logout
|
||||
GET /api/auth/profile
|
||||
PUT /api/auth/profile
|
||||
```
|
||||
|
||||
### Parking Endpoints
|
||||
```typescript
|
||||
GET /api/parking/search
|
||||
GET /api/parking/:id
|
||||
POST /api/parking/:id/reserve
|
||||
GET /api/parking/reservations
|
||||
PUT /api/parking/reservations/:id
|
||||
DELETE /api/parking/reservations/:id
|
||||
```
|
||||
|
||||
### Routing Endpoints
|
||||
```typescript
|
||||
POST /api/routing/calculate
|
||||
GET /api/routing/modes
|
||||
POST /api/routing/optimize
|
||||
```
|
||||
|
||||
### Health & Monitoring
|
||||
```typescript
|
||||
GET /api/health
|
||||
GET /api/health/database
|
||||
GET /api/health/cache
|
||||
GET /api/metrics
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗄️ Database Design
|
||||
|
||||
### Indexing Strategy
|
||||
```sql
|
||||
-- Spatial indexes for location queries
|
||||
CREATE INDEX idx_parking_lots_location ON parking_lots
|
||||
USING GIST (ll_to_earth(latitude, longitude));
|
||||
|
||||
-- Compound indexes for filtering
|
||||
CREATE INDEX idx_parking_lots_active_price ON parking_lots (is_active, price_per_hour);
|
||||
CREATE INDEX idx_parking_spots_lot_available ON parking_spots (parking_lot_id, is_occupied);
|
||||
|
||||
-- Time-based indexes for reservations
|
||||
CREATE INDEX idx_reservations_time_range ON reservations (start_time, end_time);
|
||||
CREATE INDEX idx_reservations_user_status ON reservations (user_id, status, created_at);
|
||||
```
|
||||
|
||||
### Data Partitioning
|
||||
```sql
|
||||
-- Partition reservations by month for better performance
|
||||
CREATE TABLE reservations_2024_01 PARTITION OF reservations
|
||||
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
|
||||
|
||||
-- Automated partition management
|
||||
CREATE OR REPLACE FUNCTION create_monthly_partition()
|
||||
RETURNS void AS $$
|
||||
DECLARE
|
||||
start_date date;
|
||||
end_date date;
|
||||
table_name text;
|
||||
BEGIN
|
||||
start_date := date_trunc('month', CURRENT_DATE + interval '1 month');
|
||||
end_date := start_date + interval '1 month';
|
||||
table_name := 'reservations_' || to_char(start_date, 'YYYY_MM');
|
||||
|
||||
EXECUTE format('CREATE TABLE %I PARTITION OF reservations
|
||||
FOR VALUES FROM (%L) TO (%L)',
|
||||
table_name, start_date, end_date);
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security & Performance
|
||||
|
||||
### Security Measures
|
||||
1. **Authentication**: JWT with refresh tokens
|
||||
2. **Authorization**: Role-based access control (RBAC)
|
||||
3. **Input Validation**: DTO validation with class-validator
|
||||
4. **SQL Injection**: Protected by TypeORM parameterized queries
|
||||
5. **Rate Limiting**: API rate limiting per user/IP
|
||||
6. **CORS**: Configured for specific origins
|
||||
7. **HTTPS**: TLS encryption in production
|
||||
|
||||
### Performance Optimizations
|
||||
1. **Caching**: Redis for frequently accessed data
|
||||
2. **Database**: Optimized indexes and query planning
|
||||
3. **CDN**: Static asset delivery optimization
|
||||
4. **Compression**: Gzip compression for API responses
|
||||
5. **Lazy Loading**: Component and route-based code splitting
|
||||
6. **Pagination**: Efficient pagination for large datasets
|
||||
7. **Connection Pooling**: Database connection optimization
|
||||
|
||||
### Monitoring & Logging
|
||||
```typescript
|
||||
// Health Check Implementation
|
||||
@Controller('health')
|
||||
export class HealthController {
|
||||
constructor(
|
||||
private readonly healthCheckService: HealthCheckService,
|
||||
private readonly databaseHealthIndicator: TypeOrmHealthIndicator,
|
||||
private readonly redisHealthIndicator: RedisHealthIndicator
|
||||
) {}
|
||||
|
||||
@Get()
|
||||
@HealthCheck()
|
||||
check() {
|
||||
return this.healthCheckService.check([
|
||||
() => this.databaseHealthIndicator.pingCheck('database'),
|
||||
() => this.redisHealthIndicator.checkHealth('redis'),
|
||||
() => this.checkExternalServices()
|
||||
]);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📈 Scalability Considerations
|
||||
|
||||
### Horizontal Scaling
|
||||
- **Load Balancing**: Multiple application instances
|
||||
- **Database Sharding**: Geographic or user-based sharding
|
||||
- **Microservices**: Independent service scaling
|
||||
- **CDN Integration**: Global content distribution
|
||||
|
||||
### Vertical Scaling
|
||||
- **Database Optimization**: Query optimization and indexing
|
||||
- **Memory Management**: Efficient caching strategies
|
||||
- **CPU Optimization**: Algorithmic improvements
|
||||
- **Storage Optimization**: Data archiving and compression
|
||||
|
||||
### Future Enhancements
|
||||
- **Machine Learning**: Predictive parking availability
|
||||
- **Mobile Apps**: Native iOS/Android applications
|
||||
- **Payment Integration**: Online payment processing
|
||||
- **IoT Integration**: Smart parking sensor integration
|
||||
- **Multi-language**: Internationalization support
|
||||
|
||||
---
|
||||
|
||||
*Last Updated: August 3, 2025*
|
||||
*Version: 1.0.0*
|
||||
420
Documents/TECHNICAL_SPECIFICATION.md
Normal file
420
Documents/TECHNICAL_SPECIFICATION.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# 🚗 Smart Parking Finder - Technical Specification
|
||||
|
||||
## 📋 Project Overview
|
||||
|
||||
A responsive web application that helps users find and navigate to the nearest available parking lots using OpenStreetMap and Valhalla Routing Engine with real-time availability and turn-by-turn navigation.
|
||||
|
||||
## 🎯 Core Features
|
||||
|
||||
### 🔍 Location & Discovery
|
||||
- GPS-based user location detection
|
||||
- Interactive map with nearby parking lots
|
||||
- Real-time availability display
|
||||
- Distance and direction calculation
|
||||
- Smart parking suggestions
|
||||
|
||||
### 🗺️ Navigation & Routing
|
||||
- Valhalla-powered route generation
|
||||
- Turn-by-turn directions
|
||||
- Visual route display on map
|
||||
- Estimated arrival time
|
||||
- Alternative route options
|
||||
|
||||
### 📊 Parking Information
|
||||
- Name, address, and contact details
|
||||
- Real-time available slots
|
||||
- Pricing per hour
|
||||
- Operating hours
|
||||
- Amenities and features
|
||||
|
||||
## 🏗️ System Architecture
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Frontend │ │ Backend API │ │ Database │
|
||||
│ (Next.js) │◄──►│ (NestJS) │◄──►│ PostgreSQL + │
|
||||
│ │ │ │ │ PostGIS │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Valhalla Engine │
|
||||
│ (Docker) │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
## 🔧 Technology Stack
|
||||
|
||||
### Frontend
|
||||
- **Framework**: Next.js 14 with TypeScript
|
||||
- **Map Library**: React Leaflet + OpenStreetMap
|
||||
- **UI Framework**: Tailwind CSS with custom branding
|
||||
- **State Management**: React Query + Zustand
|
||||
- **HTTP Client**: Axios with interceptors
|
||||
- **PWA Support**: Next.js PWA plugin
|
||||
|
||||
### Backend
|
||||
- **Framework**: NestJS with TypeScript
|
||||
- **Database ORM**: TypeORM with PostGIS
|
||||
- **Caching**: Redis for route caching
|
||||
- **API Documentation**: Swagger/OpenAPI
|
||||
- **Authentication**: JWT + Passport.js
|
||||
- **Rate Limiting**: Express rate limiter
|
||||
|
||||
### Infrastructure
|
||||
- **Routing Engine**: Valhalla (Docker)
|
||||
- **Database**: PostgreSQL 15 + PostGIS 3.3
|
||||
- **Deployment**: Docker Compose
|
||||
- **Monitoring**: Prometheus + Grafana
|
||||
- **CDN**: CloudFlare for static assets
|
||||
|
||||
## 📊 Database Schema
|
||||
|
||||
```sql
|
||||
-- Parking lots table
|
||||
CREATE TABLE parking_lots (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
address TEXT NOT NULL,
|
||||
location GEOGRAPHY(POINT, 4326) NOT NULL,
|
||||
lat DOUBLE PRECISION NOT NULL,
|
||||
lng DOUBLE PRECISION NOT NULL,
|
||||
hourly_rate DECIMAL(10,2),
|
||||
open_time TIME,
|
||||
close_time TIME,
|
||||
available_slots INTEGER DEFAULT 0,
|
||||
total_slots INTEGER NOT NULL,
|
||||
amenities JSONB DEFAULT '{}',
|
||||
contact_info JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT NOW(),
|
||||
updated_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Spatial index for location queries
|
||||
CREATE INDEX idx_parking_lots_location ON parking_lots USING GIST (location);
|
||||
|
||||
-- Users table (for favorites, history)
|
||||
CREATE TABLE users (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
email VARCHAR(255) UNIQUE,
|
||||
name VARCHAR(255),
|
||||
preferences JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMP DEFAULT NOW()
|
||||
);
|
||||
|
||||
-- Parking history
|
||||
CREATE TABLE parking_history (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id UUID REFERENCES users(id),
|
||||
parking_lot_id INTEGER REFERENCES parking_lots(id),
|
||||
visit_date TIMESTAMP DEFAULT NOW(),
|
||||
duration_minutes INTEGER,
|
||||
rating INTEGER CHECK (rating >= 1 AND rating <= 5)
|
||||
);
|
||||
|
||||
-- Real-time parking updates
|
||||
CREATE TABLE parking_updates (
|
||||
id SERIAL PRIMARY KEY,
|
||||
parking_lot_id INTEGER REFERENCES parking_lots(id),
|
||||
available_slots INTEGER NOT NULL,
|
||||
timestamp TIMESTAMP DEFAULT NOW(),
|
||||
source VARCHAR(50) DEFAULT 'sensor'
|
||||
);
|
||||
```
|
||||
|
||||
## 🚀 API Endpoints
|
||||
|
||||
### Parking Discovery
|
||||
```typescript
|
||||
// GET /api/parking/nearby
|
||||
interface NearbyParkingRequest {
|
||||
lat: number;
|
||||
lng: number;
|
||||
radius?: number; // meters, default 4000
|
||||
maxResults?: number; // default 20
|
||||
priceRange?: [number, number];
|
||||
amenities?: string[];
|
||||
}
|
||||
|
||||
interface NearbyParkingResponse {
|
||||
parkingLots: ParkingLot[];
|
||||
userLocation: { lat: number; lng: number };
|
||||
searchRadius: number;
|
||||
}
|
||||
```
|
||||
|
||||
### Route Planning
|
||||
```typescript
|
||||
// POST /api/routing/calculate
|
||||
interface RouteRequest {
|
||||
origin: { lat: number; lng: number };
|
||||
destination: { lat: number; lng: number };
|
||||
costing: 'auto' | 'bicycle' | 'pedestrian';
|
||||
alternatives?: number;
|
||||
}
|
||||
|
||||
interface RouteResponse {
|
||||
routes: Route[];
|
||||
summary: {
|
||||
distance: number; // km
|
||||
time: number; // minutes
|
||||
cost: number; // estimated fuel cost
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Real-time Updates
|
||||
```typescript
|
||||
// WebSocket: /ws/parking-updates
|
||||
interface ParkingUpdate {
|
||||
parkingLotId: number;
|
||||
availableSlots: number;
|
||||
timestamp: string;
|
||||
confidence: number; // 0-1
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 Brand Integration
|
||||
|
||||
Based on the existing assets in `/assets/`:
|
||||
- **Logo**: Use Logo.png for header branding
|
||||
- **Logo with Slogan**: Use Logo_and_sologan.png for splash screen
|
||||
- **Location Icons**: Integrate Location.png and mini_location.png for map markers
|
||||
|
||||
### Color Palette
|
||||
```css
|
||||
:root {
|
||||
--primary: #E85A4F; /* LACA Red */
|
||||
--secondary: #D73502; /* Darker Red */
|
||||
--accent: #8B2635; /* Deep Red */
|
||||
--success: #22C55E; /* Green for available */
|
||||
--warning: #F59E0B; /* Amber for limited */
|
||||
--danger: #EF4444; /* Red for unavailable */
|
||||
--neutral: #6B7280; /* Gray */
|
||||
}
|
||||
```
|
||||
|
||||
## 📱 UI/UX Design
|
||||
|
||||
### Layout Structure
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Header [Logo] [Search] [Profile] │
|
||||
├─────────────────┬───────────────────────┤
|
||||
│ Sidebar │ Map View │
|
||||
│ - Filters │ - User location │
|
||||
│ - Parking List │ - Parking markers │
|
||||
│ - Selected Info │ - Route overlay │
|
||||
│ - Directions │ - Controls │
|
||||
└─────────────────┴───────────────────────┘
|
||||
```
|
||||
|
||||
### Responsive Breakpoints
|
||||
- **Mobile**: < 768px (full-screen map with drawer)
|
||||
- **Tablet**: 768px - 1024px (split view)
|
||||
- **Desktop**: > 1024px (sidebar + map)
|
||||
|
||||
## 🐳 Docker Configuration
|
||||
|
||||
### Valhalla Setup
|
||||
```dockerfile
|
||||
# Dockerfile.valhalla
|
||||
FROM ghcr.io/gis-ops/docker-valhalla/valhalla:latest
|
||||
|
||||
# Copy OSM data
|
||||
COPY ./osm-data/*.pbf /custom_files/
|
||||
|
||||
# Configuration
|
||||
COPY valhalla.json /valhalla.json
|
||||
|
||||
EXPOSE 8002
|
||||
|
||||
CMD ["valhalla_service", "/valhalla.json"]
|
||||
```
|
||||
|
||||
### Docker Compose
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
frontend:
|
||||
build: ./frontend
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- NEXT_PUBLIC_API_URL=http://backend:3001
|
||||
depends_on:
|
||||
- backend
|
||||
|
||||
backend:
|
||||
build: ./backend
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
- DATABASE_URL=postgresql://user:pass@postgres:5432/parking_db
|
||||
- REDIS_URL=redis://redis:6379
|
||||
- VALHALLA_URL=http://valhalla:8002
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
- valhalla
|
||||
|
||||
postgres:
|
||||
image: postgis/postgis:15-3.3
|
||||
environment:
|
||||
- POSTGRES_DB=parking_db
|
||||
- POSTGRES_USER=user
|
||||
- POSTGRES_PASSWORD=pass
|
||||
volumes:
|
||||
- postgres_data:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6379:6379"
|
||||
|
||||
valhalla:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile.valhalla
|
||||
ports:
|
||||
- "8002:8002"
|
||||
volumes:
|
||||
- ./valhalla-data:/valhalla-data
|
||||
|
||||
volumes:
|
||||
postgres_data:
|
||||
```
|
||||
|
||||
## 🔐 Security Considerations
|
||||
|
||||
### Frontend Security
|
||||
- Content Security Policy (CSP)
|
||||
- HTTPS enforcement
|
||||
- API key protection
|
||||
- Input sanitization
|
||||
|
||||
### Backend Security
|
||||
- Rate limiting per IP
|
||||
- JWT token validation
|
||||
- SQL injection prevention
|
||||
- CORS configuration
|
||||
|
||||
### Infrastructure Security
|
||||
- Database encryption at rest
|
||||
- SSL/TLS certificates
|
||||
- Network segmentation
|
||||
- Regular security updates
|
||||
|
||||
## 📈 Performance Optimization
|
||||
|
||||
### Frontend Optimization
|
||||
- Code splitting by routes
|
||||
- Image optimization with Next.js
|
||||
- Service worker for caching
|
||||
- Lazy loading for map components
|
||||
|
||||
### Backend Optimization
|
||||
- Database query optimization
|
||||
- Redis caching for frequent requests
|
||||
- Connection pooling
|
||||
- Response compression
|
||||
|
||||
### Database Optimization
|
||||
- Spatial indexes for geo queries
|
||||
- Query result caching
|
||||
- Read replicas for scaling
|
||||
- Partitioning for large datasets
|
||||
|
||||
## 🚀 Deployment Strategy
|
||||
|
||||
### Development
|
||||
```bash
|
||||
# Local development setup
|
||||
docker-compose -f docker-compose.dev.yml up -d
|
||||
npm run dev:frontend
|
||||
npm run dev:backend
|
||||
```
|
||||
|
||||
### Production
|
||||
```bash
|
||||
# Production deployment
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
```
|
||||
|
||||
### CI/CD Pipeline
|
||||
1. **Build**: Docker images for each service
|
||||
2. **Test**: Unit tests, integration tests, E2E tests
|
||||
3. **Deploy**: Blue-green deployment strategy
|
||||
4. **Monitor**: Health checks and performance metrics
|
||||
|
||||
## 📊 Monitoring & Analytics
|
||||
|
||||
### Application Metrics
|
||||
- Response times
|
||||
- Error rates
|
||||
- User engagement
|
||||
- Route calculation performance
|
||||
|
||||
### Business Metrics
|
||||
- Popular parking locations
|
||||
- Peak usage times
|
||||
- User retention
|
||||
- Revenue per parking lot
|
||||
|
||||
## 🔄 Future Enhancements
|
||||
|
||||
### Phase 2 Features
|
||||
- Parking reservations
|
||||
- Payment integration
|
||||
- User reviews and ratings
|
||||
- Push notifications for parking alerts
|
||||
|
||||
### Phase 3 Features
|
||||
- AI-powered parking predictions
|
||||
- Electric vehicle charging stations
|
||||
- Multi-language support
|
||||
- Offline mode with cached data
|
||||
|
||||
## 📋 Implementation Timeline
|
||||
|
||||
### Week 1-2: Foundation
|
||||
- Project setup and infrastructure
|
||||
- Database schema and migrations
|
||||
- Basic API endpoints
|
||||
|
||||
### Week 3-4: Core Features
|
||||
- Map integration with Leaflet
|
||||
- Parking lot display and search
|
||||
- User location detection
|
||||
|
||||
### Week 5-6: Navigation
|
||||
- Valhalla integration
|
||||
- Route calculation and display
|
||||
- Turn-by-turn directions
|
||||
|
||||
### Week 7-8: Polish
|
||||
- UI/UX improvements
|
||||
- Performance optimization
|
||||
- Testing and bug fixes
|
||||
|
||||
### Week 9-10: Deployment
|
||||
- Production setup
|
||||
- CI/CD pipeline
|
||||
- Monitoring and analytics
|
||||
|
||||
## 🏁 Success Metrics
|
||||
|
||||
### Technical KPIs
|
||||
- Page load time < 2 seconds
|
||||
- Route calculation < 3 seconds
|
||||
- 99.9% uptime
|
||||
- Zero security vulnerabilities
|
||||
|
||||
### User Experience KPIs
|
||||
- User retention > 60%
|
||||
- Average session time > 5 minutes
|
||||
- Route accuracy > 95%
|
||||
- User satisfaction score > 4.5/5
|
||||
|
||||
This comprehensive specification provides a solid foundation for building a world-class parking finder application with modern web technologies and best practices.
|
||||
Reference in New Issue
Block a user