Back to SL Mar

MarineWatcher

Marine Intelligence Platform — Technical Reference

MarineWatcher feed view

Real-time maritime regulatory monitoring and intelligence platform. Aggregates news and regulatory updates from 17 industry sources (10 RSS + 7 HTML scrapers), classifies articles by IMO convention, vessel type, geographic zone and urgency level, and provides on-demand AI summaries via a local LLM. Integrates AIS-based fleet tracking to monitor vessel positions in real time, and visualises piracy incidents from the IMB Live Piracy Map on an interactive map with proximity alerts.

Architecture

┌─────────────────────────────────────────────────────────┐
│              React 18 + TypeScript + Tailwind            │
│  Feed │ Timeline │ Sources │ Map │ Settings │ Detail     │
├─────────────────────────────────────────────────────────┤
│          REST API + WebSocket (AIS stream)               │
├─────────────────────────────────────────────────────────┤
│                FastAPI + SQLAlchemy 2.0                   │
│  Scheduler │ Classifier │ Enrichment │ Notifier │ AIS    │
├──────────────┬──────────────┬───────────────────────────┤
│  PostgreSQL  │    Ollama    │     AIS Stream API         │
└──────────────┴──────────────┴───────────────────────────┘

Frontend — React 18, TypeScript, Vite 6, Tailwind CSS, Zustand, TanStack React Query. Leaflet map with CARTO dark tiles, zone-based urgency clustering, and live AIS vessel markers.

Backend — FastAPI, SQLAlchemy 2.0 async, Pydantic v2. APScheduler polls sources every 30 minutes. On-demand LLM enrichment via Ollama (no batch processing — summaries generated only when requested). Telegram Bot API for push notifications.

Data — PostgreSQL with GIN indexes for full-text search and array overlap queries. Feed deduplication via SHA256 GUID generation. AIS positions stored as upsert (latest position per vessel) with 12-hour track sampling for historical playback.

Installation

# Prerequisites: Docker, Docker Compose
# PostgreSQL instance accessible on the network
# Ollama with qwen2.5:32b (optional — only needed for AI summaries)

docker compose up -d

The init container creates the database and runs migrations automatically on first start.

  • Frontend: http://localhost:3006
  • API: http://localhost:8006
  • Health: http://localhost:8006/api/health

Configuration

Copy .env.example to .env:

MW_DATABASE_URL=postgresql+asyncpg://postgres:postgres@qm-db:5432/marinewatcher
MW_POLL_INTERVAL_MINUTES=30
MW_AIS_API_KEY=<your-aisstream-key>

Ollama is accessed via host.docker.internal:11434 from inside the container. The app works without Ollama — AI summaries simply won't be available.

Tech Stack

LayerTechnology
FrontendReact 18, TypeScript, Vite 6, Tailwind CSS
StateZustand, TanStack React Query
BackendFastAPI, SQLAlchemy 2.0 async, Pydantic v2
SchedulingAPScheduler (AsyncIOScheduler)
DatabasePostgreSQL 16, asyncpg, GIN indexes
LLMOllama (qwen2.5:32b), on-demand only
MapsLeaflet, react-leaflet, CARTO tiles
AISWebSocket client (aisstream.io)
NotificationsTelegram Bot API
DeploymentDocker Compose (3 containers)

Feed Aggregation

17 RSS and HTML sources polled every 30 minutes via APScheduler. New articles are deduplicated by SHA256(source_id:entry_id) and classified automatically on ingestion.

RSS/Atom Feeds (10)

  • EMSA News & Publications
  • gCaptain, Maritime Executive
  • Seatrade, Hellenic Shipping News
  • Splash247, Offshore Energy
  • INTERTANKO

HTML Scrapers (7)

  • IMO Press Briefings
  • OCIMF Bulletins
  • ReCAAP Incident Alerts
  • MARAD Maritime Advisories
  • UKMTO Warnings
  • NATO Shipping Centre
  • MDAT-GoA Advisories

Classification Engine

Every ingested article is classified across four dimensions using regex-based keyword matching.

Conventions (25+)

MARPOL, SOLAS, STCW, MLC, ISM, ISPS, IMSBC, IMDG, GHG, EU-ETS, EU-MRV, FuelEU, CII, EEXI, Polar Code, AFS, HNS, LL, COLREG, VETTING (SIRE, CDI, OCIMF, RightShip, TMSA, PSC).

Vessel Types

Bulk carriers, tankers (crude/product/chemical), containers, LNG/LPG, passenger/cruise, RoRo, offshore/FPSO, fishing, superyachts, tugs.

Geographic Zones (16)

EU, North Sea, Baltic, Mediterranean, Black Sea, Red Sea, Middle East, West Africa, SE Asia, Indian Ocean, Arctic, SECA, ECA, US, China, Global.

Urgency Levels

LevelTriggers
Criticalban, detention, vessel sank, missile strike, crew killed
Highmandatory requirement, deadline, piracy attack, sanctions
Mediumguidance, advisory, bulletin
Lowstudy, report, conference
Infodefault for unmatched articles

AI Enrichment

On-demand LLM summaries via local Ollama (qwen2.5:32b). No external API calls, no batch processing — the LLM is queried only when a user clicks “Get AI Summary” on a specific article.

The enrichment prompt extracts:

  • 2–3 sentence summary
  • Conventions, vessel types, zones (merged with keyword tags)
  • Urgency assessment
  • Effective date (regulatory entry-into-force, if mentioned)

Interactive Map

MarineWatcher map view

Leaflet map with CARTO dark tiles (no labels). Three layers:

Zone Clustering

Articles grouped by geographic zone, rendered as sized/coloured circles. Circle radius scales with article count, colour reflects highest urgency in the zone. Click to browse articles in that zone.

Piracy Incidents

Live piracy incident data from the IMB Live Piracy Map, displayed as red skull markers. Proximity alerts trigger Telegram notifications when a fleet vessel is within 50 NM of a reported incident.

Fleet Tracking (AIS)

Live AIS vessel positions as rotatable SVG arrow markers. Dashed polyline breadcrumbs from 12-hour track history. Fleet panel shows vessel status, speed, and time since last update.

Fleet Tracking

Fleet tracking panel

WebSocket connection to AIS stream API for real-time position updates:

  • Position reports — lat/lng/speed/course/heading upsert to a single-row-per-vessel table
  • Track points — sampled every 12 hours for historical playback
  • Ship static data — IMO number, name, destination merged on receipt
  • Connection recovery — exponential backoff (5, 10, 30, 60 seconds)

The fleet panel displays online/offline status, current speed, and destination for each tracked vessel.

Telegram Notifications

Telegram notification settings

Configurable push alerts via Telegram Bot API:

  • Urgency threshold — minimum urgency level to trigger alerts (e.g., “high” sends critical + high)
  • Convention filter — only alert on specific conventions (empty = all)
  • Zone filter — only alert on specific zones (empty = all)
  • Rate limiting — max 10 messages per poll cycle, overflow summarised
  • Test button — sends a verification message to confirm bot token and chat ID

Timeline

Regulatory deadlines extracted from articles with effective dates. Grouped by month, sorted chronologically, with “UPCOMING” badges for future dates. Useful for tracking convention entry-into-force dates, vetting inspection deadlines, and compliance cutoffs.

Sources

MarineWatcher sources panel
SourceTypeCategory
EMSA NewsRSSEU
EMSA PublicationsRSSEU
gCaptainRSSNews
Maritime ExecutiveRSSNews
Seatrade MaritimeRSSNews
Hellenic Shipping NewsRSSNews
Splash247RSSNews
Offshore EnergyRSSNews
INTERTANKORSSTanker Org
IMO Press BriefingsHTMLIMO
OCIMF BulletinsHTMLTanker Org
ReCAAP AlertsHTMLSecurity
MARAD AdvisoriesHTMLSecurity
UKMTO WarningsHTMLSecurity
NATO Shipping CentreHTMLSecurity
MDAT-GoAHTMLSecurity
IMB Piracy MapAPISecurity

API Reference

GET /api/items

Paginated feed items with filters: search, conventions, vessel types, zones, urgency, effective date.

GET /api/items/:id

Single item with source metadata.

PATCH /api/items/:id

Mark item as read.

POST /api/items/:id/enrich

Request AI summary for one item (on-demand, via Ollama).

GET /api/sources

List active feed sources.

GET /api/stats

Dashboard counters: items today, critical alerts, active sources, upcoming deadlines.

GET /api/vessels

Current vessel positions (real-time AIS data).

GET /api/vessels/tracks

Historical vessel positions (configurable day range).

GET /api/piracy/incidents

Piracy incidents from IMB Live Piracy Map.

GET /api/notifications/settings

Telegram notification configuration.

PUT /api/notifications/settings

Update notification filters and credentials.

POST /api/notifications/test

Send test Telegram message.

Database Schema

Six tables with GIN indexes for performant filtering:

TablePurposeKey Columns
sourcesFeed definitionsname, url, feed_type (rss/atom/html), last_polled_at
feed_itemsArticlestitle, summary, conventions[], vessel_types[], zones[], urgency, llm_summary, effective_date
notification_settingsTelegram configbot_token, chat_id, min_urgency, conventions[], zones[]
vessel_positionsCurrent AIS positionmmsi (PK), lat, lng, speed, course, heading, destination
vessel_tracksHistorical breadcrumbsmmsi, lat, lng, speed, course, recorded_at
piracy_incidentsIMB piracy reportsimb_id (PK), lat, lng, incident_type, vessel_name, description, date
Indexing

GIN indexes on conventions, vessel_types, and zones arrays enable sub-millisecond filtering via PostgreSQL array overlap operators. Trigram GIN indexes on title and summary support full-text search.

Dev Log

v0.0.1 — 7 March 2026

Public announcement. Baseline version.

Feed aggregation from 17 sources (10 RSS + 7 HTML scrapers), regex-based classification engine, on-demand AI enrichment via Ollama, interactive Leaflet map with zone clustering and piracy incident markers, AIS fleet tracking with proximity alerts, Telegram notification layer, regulatory timeline view. Full REST API with paginated filtering.