Skip to content

Full-stack AI powered maritime tracking application that provides real-time vessel monitoring, intelligent destination decoding, and maritime assistance. Built with modern web technologies and designed for scalability, this system demonstrates advanced data processing, API integration, and real-time data visualization.

License

Notifications You must be signed in to change notification settings

ryantusi/GMS_Vessel_Tracker

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🚒 Live Ship Vessel Tracker

Netlify Status Backend Status Flask API

Real-time maritime vessel tracking system with AI-powered assistance and intelligent port destination decoding

Live Demo β€’ API Documentation β€’ Video Demo (Under Development) β€’ Report Bug


πŸ“– Table of Contents


🌟 Overview

Live Ship Vessel Tracker is a comprehensive full-stack maritime tracking application that provides real-time vessel monitoring, intelligent destination decoding, and AI-powered maritime assistance. Built with modern web technologies and designed for scalability, this system demonstrates advanced data processing, API integration, and real-time data visualization.

🎯 What Makes This Special?

  1. Intelligent AIS Destination Decoding - Transforms messy, unpredictable AIS destination codes into clean, readable port names and countries
  2. Batch Processing - Track up to 20 vessels simultaneously with a single request
  3. AI-Powered Chatbot (COMPASS) - Get instant information about vessels, ports, and maritime routes using Google's Gemini AI
  4. Real-Time Caching - Redis-powered caching system reduces API calls by 80-90% and improves response times
  5. Interactive Mapping - Mapbox integration with custom markers for vessels and destination ports

✨ Key Features

πŸ” Core Functionality

  • Single Vessel Tracking

    • Search by IMO number
    • View current position on interactive map
    • See detailed vessel specifications
    • Track destination port with coordinates
    • Real-time navigation status
  • Batch Vessel Search

    • Process up to 20 vessels simultaneously
    • Bulk data retrieval and normalization
    • Aggregated results with success/failure tracking
    • Export capabilities for data analysis
  • Smart Destination Decoding

    • Handles 15+ AIS destination formats
    • UN/LOCODE to readable port names
    • Multi-format parsing (BEZEE<>GBHUL, SGSIN=>BRPMA, etc.)
    • Fuzzy matching with 98% accuracy
    • Country and port coordinate resolution

πŸ€– AI-Powered Features

  • COMPASS AI Assistant
    • Context-aware conversations about vessels
    • Maritime knowledge database
    • Vessel specification queries
    • Port information and routing advice
    • Powered by Google Gemini AI

⚑ Performance Features

  • Redis Caching Layer

    • 7-day TTL (Time To Live)
    • 80-90% cache hit rate
    • Sub-50ms response times for cached data
    • Automatic cache invalidation
  • Efficient Data Processing

    • Batch processing with rate limiting
    • Parallel API calls
    • Optimized database queries
    • Lazy loading for improved UX

πŸ—ΊοΈ Visualization

  • Interactive Maps (Mapbox GL)
    • Dark theme optimized for maritime data
    • Custom vessel markers
    • Destination port indicators
    • Auto-fit bounds
    • Zoom and navigation controls
    • Popup information on hover

🎯 The Problem I Solved

The Challenge: Messy AIS Destination Data

AIS (Automatic Identification System) destination data is notoriously inconsistent and difficult to interpret. Vessels report their destinations in various unpredictable formats:

❌ Raw AIS Data Problems:
"BEZEE <> GBHUL"     β†’ What does this mean?
"SGSIN=>BRPMA"       β†’ Which ports are these?
"LYBEN>>MTMAR"       β†’ Arrows? Really?
"TR IST"             β†’ UN/LOCODE format
"PORT SAID"          β†’ Full name (ambiguous)
"TBA"                β†’ To Be Announced (no info)
"GIBRALTAR EAST ANCH" β†’ Port + Anchorage area

Solution: Intelligent Decoding Engine

βœ… Our System Transforms:
"BEZEE <> GBHUL"     β†’ Zeebrugge, Belgium β†’ Hull, United Kingdom
"SGSIN=>BRPMA"       β†’ Singapore β†’ ParanaguΓ‘, Brazil
"LYBEN>>MTMAR"       β†’ Benghazi, Libya β†’ Marsa, Malta
"TR IST"             β†’ Istanbul, Turkey (41.0082Β°N, 28.9784Β°E)
"PORT SAID"          β†’ Port Said, Egypt (31.2565Β°N, 32.2841Β°E)

How did I Do It:

  1. Pattern Recognition - 15+ format parsers for different AIS conventions
  2. UN/LOCODE Matching - Database of 100,000+ maritime locations
  3. Fuzzy Matching - 98% accuracy with intelligent similarity algorithms
  4. Route Extraction - Identifies final destination from multi-leg routes
  5. Geocoding - Provides precise coordinates for map visualization

πŸ—οΈ System Architecture

High-Level Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         USER BROWSER                            β”‚
β”‚                  (React + Mapbox + Tailwind)                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚                β”‚
                    β–Ό                β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  Express.js    β”‚     β”‚  Flask Backend β”‚
        β”‚  Backend API   β”‚     β”‚  (AI-Model)    β”‚
        β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€     β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
        β”‚ β€’ Vessel Data  β”‚     β”‚ β€’ AIS Decoder  β”‚
        β”‚ β€’ Normalizationβ”‚---->β”‚ β€’ Gemini AI    β”‚
        β”‚ β€’ Map Data     β”‚     β”‚ β€’ Port Matcher β”‚
        β”‚ β€’ Redis Cache  β”‚     β”‚ β€’ UN/LOCODE DB β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚                      β”‚
                 β–Ό                      β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  Redis Cache   β”‚     β”‚  locode.json   β”‚
        β”‚  (7-day TTL)   β”‚     β”‚ (Port Database)β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 β–Ό
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚  AIS Friends   β”‚
        β”‚  API Endpoint  β”‚
        β”‚ (Discovered)   β”‚
        β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Component Interaction

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                          Request Flow                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

1. User Input (IMO: 9626390)
   β”‚
   β”œβ”€β†’ Frontend React Component
   β”‚    └─→ API Service (axios)
   β”‚
2. Express Backend Receives Request
   β”‚
   β”œβ”€β†’ Check Redis Cache
   β”‚    β”œβ”€β†’ HIT: Return cached data (50ms)
   β”‚    └─→ MISS: Continue to API
   β”‚
3. Fetch from AIS Friends API
   β”‚    └─→ Raw vessel data retrieved
   β”‚
4. Data Normalization
   β”‚
   β”œβ”€β†’ Normalize vessel name & type
   β”‚
   β”œβ”€β†’ Send AIS destination to Flask
   β”‚    β”‚
   β”‚    β”œβ”€β†’ Flask Port Matcher
   β”‚    β”‚    β”œβ”€β†’ Pattern extraction
   β”‚    β”‚    β”œβ”€β†’ UN/LOCODE matching
   β”‚    β”‚    β”œβ”€β†’ Fuzzy matching
   β”‚    β”‚    └─→ Coordinate resolution
   β”‚    β”‚
   β”‚    └─→ Return: {port, country, lat, lon}
   β”‚
   β”œβ”€β†’ Generate Mapbox markers
   β”‚
   └─→ Store in Redis (7-day TTL)
   β”‚
5. Return to Frontend
   β”‚
   └─→ Display: Map + Details + Table


   User Initializes Chatbot
   β”‚
   └─→ Flask: Connects to Gemini API and initiates messaging


πŸ› οΈ Technology Stack

Frontend

  • React 18.3.1 - UI framework with hooks
  • React Router 6 - Client-side routing
  • Tailwind CSS v4 - Utility-first styling
  • Mapbox GL JS - Interactive maps
  • Axios - HTTP client
  • Lucide React - Icon library
  • Vite - Build tool & dev server

Backend (Express)

  • Node.js 18+ - Runtime environment
  • Express.js 4.18 - Web framework
  • Redis 4.6 - Caching layer
  • node-fetch 3.3 - HTTP requests
  • dotenv - Environment management
  • CORS - Cross-origin resource sharing

Backend (Flask - AI-Model)

  • Python 3.10+ - Runtime
  • Flask 3.0 - Micro framework
  • Flask-CORS - CORS handling
  • Google Generative AI - Gemini integration
  • Gunicorn - WSGI server
  • Custom Port Matcher - UN/LOCODE algorithm

Infrastructure & Services

  • Redis - In-memory data store
  • Netlify - Frontend hosting
  • Render - Backend hosting (Flask + Express)
  • Mapbox - Map tiles and geocoding
  • AIS Friends API - Vessel data source
  • Google Gemini - AI chatbot
  • Ollama Mistral - Local AI Model (testing prompt engineering)

Development Tools

  • Jest - Testing framework
  • ESLint - Code linting
  • Git - Version control
  • GitHub - Repository Storage

πŸ“Š Data Flow

Single Vessel Request

sequenceDiagram
    participant User
    participant Frontend
    participant Express
    participant Redis
    participant AIS API
    participant Flask
    participant Gemini

    User->>Frontend: Search IMO: 9626390
    Frontend->>Express: GET /api/vessel/9626390
    Express->>Redis: Check cache
    
    alt Cache Hit
        Redis-->>Express: Return cached data
        Express-->>Frontend: Vessel data + map
    else Cache Miss
        Express->>AIS API: Fetch vessel data
        AIS API-->>Express: Raw vessel data
        Express->>Flask: POST /api/destination {dest: "TR IST"}
        Flask->>Flask: UN/LOCODE matching
        Flask-->>Express: {port: "Istanbul", country: "Turkey"}
        Express->>Express: Generate map data
        Express->>Redis: Store (7-day TTL)
        Express-->>Frontend: Vessel data + map
    end
    
    Frontend->>User: Display map + details
    
    User->>Frontend: Click chatbot
    Frontend->>Flask: POST /api/chat/init
    Flask->>Gemini: Initialize session
    Gemini-->>Flask: Greeting message
    Flask-->>Frontend: AI response
    Frontend->>User: Show chat interface
Loading

Batch Vessel Request

User Input: [9626390, 9377418, 7349106]
     β”‚
     β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Express: Check Redis for all IMOs  β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Found in cache: [9626390]          β”‚ ← 1/3 cached
β”‚  Need to fetch: [9377418, 7349106]  β”‚ ← 2/3 fetch
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
        β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
        β”‚                   β”‚
        β–Ό                   β–Ό
   [Cached]           [Fetch from API]
   9626390            9377418, 7349106
        β”‚                   β”‚
        β”‚              β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β”€β”
        β”‚              β”‚         β”‚
        β”‚         Normalize   Normalize
        β”‚         9377418     7349106
        β”‚              β”‚         β”‚
        β”‚              β”Œβ”€β”€β”€β”€-────┐    
        β”‚              β–Ό         β–Ό    
        β”‚          Flask API  Flask API
        β”‚              β”‚         β”‚
        β”‚              β–Ό         β–Ό
        β”‚           Store     Store
        β”‚           Cache     Cache
        β”‚              β”‚         β”‚
        └─────────-─────────-────┐
                                  β–Ό
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β”‚  Combine all 3 vessels     β”‚
                  β”‚  Generate batch map data   β”‚
                  β”‚  Return to frontend        β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Getting Started

Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js (v18.0.0 or higher)

    node --version  # Should be >= 18.0.0
  • npm (comes with Node.js)

    npm --version
  • Python (v3.10 or higher)

    python --version  # Should be >= 3.10
  • Redis (v6.0 or higher)

    redis-server --version
  • Git

    git --version

Installation

1️⃣ Clone the Repository

git clone https://github.com/ryantusi/GMS_Vessel_Tracker.git
cd vessel-tracker

2️⃣ Set Up Backend (Express)

cd backend

# Install dependencies
npm install

# Create environment file
cp .env.example .env

# Edit .env with your credentials
# Required variables:
# - DESTINATION_DECODER_API (Flask URL)
# - MAPBOX_ACCESS_TOKEN (from Mapbox)
# - REDIS_URL (Redis connection string)

Backend .env file:

# Flask API
DESTINATION_DECODER_API=http://127.0.0.1:10000/api/destination
AI_CHATBOT_API=http://127.0.0.1:10000/api/chat

# Server Configuration
PORT=5000
NODE_ENV=development

# Mapbox Configuration
MAPBOX_ACCESS_TOKEN=your_mapbox_token_here
MAPBOX_STYLE=mapbox://styles/your_style_here

# Redis Cache
REDIS_URL=redis://localhost:6379

# CORS
ALLOWED_ORIGINS=http://localhost:3000,http://localhost:5173

3️⃣ Set Up Flask Backend (AI-Model)

cd ../AI-Model

# Create virtual environment
python -m venv venv

# Activate virtual environment
# On Windows:
venv\Scripts\activate
# On Mac/Linux:
source venv/bin/activate

# Install dependencies
pip install -r requirements.txt

# Create environment file
cp .env.example .env

# Edit .env with your Gemini API key

Flask .env file:

PORT=10000
GEMINI_API_KEY=your_gemini_api_key_here

Get Gemini API Key:

  1. Go to https://makersuite.google.com/app/apikey
  2. Create new API key
  3. Copy and paste into .env

4️⃣ Set Up Frontend (React)

cd ../frontend

# Install dependencies
npm install

# Create environment file
cp .env.example .env

# Edit .env with API URLs

Frontend .env file:

# Backend API URL
VITE_API_URL=http://localhost:5000

# Mapbox Token
VITE_MAPBOX_TOKEN=your_mapbox_token_here

# Flask Backend
VITE_FLASK_API_URL=http://127.0.0.1:10000

Get Mapbox Token:

  1. Go to https://account.mapbox.com/
  2. Create account (free)
  3. Copy your default public token
  4. Or create a new token with appropriate scopes

5️⃣ Start Redis Server

# On Windows (if installed via MSI):
redis-server

# On Mac (with Homebrew):
brew services start redis

# On Linux:
sudo systemctl start redis-server

# Or using Docker:
docker run -d --name redis -p 6379:6379 redis:latest

Verify Redis is running:

redis-cli ping
# Should return: PONG

Running the Application

Open three separate terminal windows:

Terminal 1: Flask Backend

cd AI-Model
source venv/bin/activate  # On Windows: venv\Scripts\activate
python app.py

Expected output:

βœ… Mock database loaded: 20 vessels
 * Running on http://127.0.0.1:10000

Terminal 2: Express Backend

cd backend
npm start

Expected output:

βœ… Redis connected successfully
🚒 Ship Tracker API running on port 5000
πŸ’Ύ Redis cache: ENABLED

Terminal 3: Frontend

cd frontend
npm run dev

Expected output:

VITE v5.4.10  ready in 543 ms

➜  Local:   http://localhost:5173/
➜  Network: use --host to expose

Access the Application

Open your browser and navigate to:

http://localhost:5173

You should see:

  • βœ… Disclaimer modal (explaining demo mode)
  • βœ… Home page with search forms
  • βœ… Interactive map centered on Suez Canal
  • βœ… No console errors

Test the Features

Test Single Vessel Search:

  1. Enter IMO: 9626390
  2. Click "Search Vessel"
  3. Should display vessel details and map
  4. Enter wrong IMO: 9711819
  5. Should display a clean error message

Test Batch Search:

  1. Enter IMOs: 99626390, 9377418, 7349106, 9711819 (wrong imo)
  2. Click "Search Multiple Vessels"
  3. Should display results table

Test AI Chatbot:

  1. Click the floating chat button (bottom-right)
  2. Chat panel opens
  3. Type: "What is the status of vessel 9626390?"
  4. COMPASS responds with vessel information

πŸ“ Project Structure

vessel-tracker/
β”œβ”€β”€ AI-Model/                    # Flask backend for AI & destination decoding
β”‚   β”œβ”€β”€ chatbot/                 # Gemini AI chatbot implementation
β”‚   β”‚   β”œβ”€β”€ chatbot.py          # Main chatbot logic
β”‚   β”‚   └── testbot.py          # Ollama test version
β”‚   β”œβ”€β”€ helper/                  # Utility functions
β”‚   β”‚   β”œβ”€β”€ ais_port_matcher.py # UN/LOCODE matching algorithm
β”‚   β”‚   β”œβ”€β”€ script.py           # Database generation script
β”‚   β”‚   β”œβ”€β”€ code-list.csv       # UN/LOCODE port codes
β”‚   β”‚   β”œβ”€β”€ country-codes.csv   # Country reference data
β”‚   β”‚   └── locode.json         # Generated port database (100K+ entries)
β”‚   β”œβ”€β”€ app.py                   # Flask application & routes
β”‚   β”œβ”€β”€ requirements.txt         # Python dependencies
β”‚   β”œβ”€β”€ mock-vessels.json        # Mock vessel database (deployment)
β”‚   └── .env                     # Environment variables
β”‚
β”œβ”€β”€ backend/                     # Express.js backend API
β”‚   β”œβ”€β”€ utils/                   # Utility modules
β”‚   β”‚   β”œβ”€β”€ apiData.js          # AIS data fetching
β”‚   β”‚   β”œβ”€β”€ normalizer.js       # Data normalization
β”‚   β”‚   β”œβ”€β”€ mapbox.js           # Map data generation
β”‚   β”‚   └── cache.js            # Redis caching service
β”‚   β”œβ”€β”€ tests/                   # Unit tests
β”‚   β”‚   β”œβ”€β”€ server.test.js      # API endpoint tests
β”‚   β”‚   └── setup.js            # Test configuration
β”‚   β”œβ”€β”€ server.js                # Express server & routes
β”‚   β”œβ”€β”€ package.json             # Node dependencies
β”‚   β”œβ”€β”€ jest.config.js           # Jest configuration
β”‚   β”œβ”€β”€ mock-vessels.json        # Mock data (deployment)
β”‚   └── .env                     # Environment variables
β”‚
β”œβ”€β”€ frontend/                    # React frontend application
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ components/          # React components
β”‚   β”‚   β”‚   β”œβ”€β”€ Chatbot.jsx     # AI chatbot interface
β”‚   β”‚   β”‚   β”œβ”€β”€ DisclaimerModal.jsx  # Demo disclaimer
β”‚   β”‚   β”‚   β”œβ”€β”€ ErrorMessage.jsx     # Error handling
β”‚   β”‚   β”‚   β”œβ”€β”€ Footer.jsx           # Page footer
β”‚   β”‚   β”‚   β”œβ”€β”€ LoadingSpinner.jsx   # Loading states
β”‚   β”‚   β”‚   └── MapComponent.jsx     # Mapbox integration
β”‚   β”‚   β”œβ”€β”€ pages/               # Page components
β”‚   β”‚   β”‚   β”œβ”€β”€ Home.jsx        # Landing page
β”‚   β”‚   β”‚   β”œβ”€β”€ SingleVessel.jsx     # Vessel details
β”‚   β”‚   β”‚   └── BatchVessels.jsx     # Batch results
β”‚   β”‚   β”œβ”€β”€ services/            # API services
β”‚   β”‚   β”‚   └── api.js          # Axios API client
β”‚   β”‚   β”œβ”€β”€ App.jsx              # Root component
β”‚   β”‚   β”œβ”€β”€ main.jsx             # React entry point
β”‚   β”‚   └── index.css            # Global styles
β”‚   β”œβ”€β”€ public/                  # Static assets
β”‚   β”œβ”€β”€ package.json             # Node dependencies
β”‚   β”œβ”€β”€ vite.config.js           # Vite configuration
β”‚   β”œβ”€β”€ tailwind.config.js       # Tailwind CSS config
β”‚   └── .env                     # Environment variables
β”‚
β”œβ”€β”€ database/                    # Mock database (deployment)
β”‚   └── mock-vessels.json        # 20 vessels for demo
β”‚
β”œβ”€β”€ docs/                        # Documentation
β”‚   └── setup-guides/            # Setup instructions
β”‚
β”œβ”€β”€ .gitignore                   # Git ignore rules
β”œβ”€β”€ LICENSE                      # MIT License
└── README.md                    # This file

🌐 API Endpoints

Express Backend (http://localhost:5000)

Root

GET /

Returns API information and available endpoints.

Single Vessel

GET /api/vessel/:imo

Parameters:

  • imo - IMO number (7-10 digits)

Response:

{
  "success": true,
  "vessel": {
    "imo": "9626390",
    "name": "Ruby",
    "type": "mv",
    "ais_destination": {
      "destination": "Istanbul, Turkey",
      "port": "Istanbul",
      "country": "Turkey",
      "lat": 41.0082,
      "lon": 28.9784
    },
    "latitude": 41.125858,
    "longitude": 29.078135,
    "navigational_status": "Underway using engine",
    "speed_over_ground": 10.0,
    "reportedDestination": "TR IST"
  },
  "map": {
    "markers": [...],
    "bounds": [[lng1, lat1], [lng2, lat2]],
    "center": [lng, lat]
  },
  "cached": false
}

Batch Vessels

POST /api/vessels/batch
Content-Type: application/json

{
  "imos": ["9626390", "9377418", "7349106"]
}

Response:

{
  "success": true,
  "totalRequested": 3,
  "totalSuccess": 3,
  "totalFailed": 0,
  "cachedCount": 1,
  "fetchedCount": 2,
  "vessels": [...],
  "map": {...}
}

Cache Stats

GET /api/cache/stats

Clear Cache

DELETE /api/cache/vessel/:imo

Flask Backend (http://localhost:10000)

Root

GET /

Decode Destination

POST /api/destination
Content-Type: application/json

{
  "destination": "TR IST"
}

Response:

{
  "reportedDestination": "TR IST",
  "locode": "TRIST",
  "port": "Istanbul",
  "country": "Turkey",
  "lat": 41.0082,
  "lon": 28.9784,
  "matched": true
}

Initialize Chat

GET /api/chat/init

Send Chat Message

POST /api/chat
Content-Type: application/json

{
  "message": "What is the status of vessel 9626390?"
}

πŸš€ Deployment

Deployment Stack

  • Frontend: Netlify
  • Express Backend: Render
  • Flask Backend: Render

Quick Deployment

See detailed deployment guide: DEPLOYMENT.md

Summary:

  1. Deploy Flask β†’ Get URL
  2. Deploy Express β†’ Update with Flask URL
  3. Deploy Frontend β†’ Update with both backend URLs
  4. Update CORS settings

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Commit changes (git commit -m 'Add AmazingFeature')
  4. Push to branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the CC0 1.0 Universal - see the LICENSE file for details.


πŸ™ Acknowledgments

  • AIS Friends API - For providing accessible AIS vessel data (and for blocking my hosting priviledges everywhere)
  • UN/LOCODE - Maritime location code system
  • Mapbox - Interactive mapping platform
  • Google Gemini - AI language model
  • Ollama Mistral - AI Model for prompt engineering
  • Open Source Community - For amazing tools and libraries

πŸ“§ Contact

Ryan Tusi - LinkedIn

Portfolio: Click


AI-Model Flask | Express Backend | React Frontend

Built for the maritime industry. Engineered and Developed by Ryan Tusi, Full Stack + AI/ML Engineer

βš“οΈ 🚒 🌊

About

Full-stack AI powered maritime tracking application that provides real-time vessel monitoring, intelligent destination decoding, and maritime assistance. Built with modern web technologies and designed for scalability, this system demonstrates advanced data processing, API integration, and real-time data visualization.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published