Files
website/docs/HARBORSMITH_IMPLEMENTATION_PLAN.md
matt ec72c5d62b
Some checks failed
build-website / build (push) Failing after 1m2s
Initial import of HarborSmith website
2025-09-18 22:20:01 +02:00

1416 lines
41 KiB
Markdown

# HarborSmith Platform Implementation Plan
## Complete Technical Guide for Production Development
**Version:** 1.0
**Date:** September 2025
**Status:** Ready for Development
---
## 📋 Executive Summary
HarborSmith is a comprehensive marine services platform bridging yacht owners and maritime service providers through two primary verticals: **Maintenance Services** and **Charter Services**. This document provides the complete technical implementation plan for migrating from HTML mockups to a production-ready platform using modern, scalable architecture without cutting corners.
### Key Objectives
- Build a robust, scalable platform from day one
- Implement microservices architecture for future growth
- Ensure enterprise-grade security with SSO
- Enable real-time capabilities for enhanced UX
- Maintain SEO optimization through SSR
- Deploy rapidly without compromising quality
---
## 🏗️ Technology Stack
### Core Technologies
```yaml
# Frontend
Framework: Next.js 14 (App Router)
Language: TypeScript
Styling: TailwindCSS + Shadcn/UI
State Management: Zustand + TanStack Query
Forms: React Hook Form + Zod
SEO: Server-Side Rendering (SSR)
# Backend
Architecture: Microservices
Runtime: Node.js
Framework: Fastify
API Design: RESTful
Validation: Zod
Documentation: OpenAPI/Swagger
# Database
Primary: Supabase (PostgreSQL)
Cache: Redis
Real-time: Supabase Realtime
File Storage: MinIO S3
# Authentication
SSO Provider: Keycloak
Session Management: JWT + Refresh Tokens
Authorization: RBAC with Casbin
# Infrastructure
Containerization: Docker
Reverse Proxy: Nginx
Orchestration: Docker Compose → Kubernetes (future)
Monitoring: Umami Analytics
# Third-Party Services
Payments: Stripe
Invoicing: InvoiceNinja API
Email: Poste.io (SMTP)
Marketing: Listmonk
Maps: Mapbox
Weather: OpenWeatherMap
CMS: Directus
```
---
## 📁 Project Structure
```bash
harborsmith-platform/
├── docker-compose.yml # Production orchestration
├── docker-compose.dev.yml # Development overrides
├── .env.example # Environment variables template
├── Makefile # Common commands and shortcuts
├── README.md # Project overview
├── docs/ # Documentation
│ ├── HARBORSMITH_IMPLEMENTATION_PLAN.md (this file)
│ ├── API_DOCUMENTATION.md
│ ├── DEPLOYMENT_GUIDE.md
│ └── TROUBLESHOOTING.md
├── nginx/ # Reverse proxy configuration
│ ├── nginx.conf # Main Nginx config
│ ├── ssl/ # SSL certificates
│ └── sites/
│ ├── app.conf # Frontend routing
│ ├── api.conf # API gateway routing
│ └── services.conf # Microservices routing
├── apps/
│ ├── web/ # Next.js Frontend Application
│ │ ├── src/
│ │ │ ├── app/ # App Router pages
│ │ │ │ ├── (public)/ # Public routes
│ │ │ │ │ ├── page.tsx # Homepage
│ │ │ │ │ ├── charter/
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── booking/
│ │ │ │ │ │ ├── [step]/page.tsx
│ │ │ │ │ │ └── components/
│ │ │ │ │ ├── maintenance/
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ └── booking/
│ │ │ │ │ ├── about/
│ │ │ │ │ ├── contact/
│ │ │ │ │ └── faq/
│ │ │ │ ├── (auth)/ # Protected routes
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ ├── dashboard/
│ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ ├── charter/
│ │ │ │ │ │ └── maintenance/
│ │ │ │ │ ├── vessels/
│ │ │ │ │ ├── bookings/
│ │ │ │ │ ├── documents/
│ │ │ │ │ ├── invoices/
│ │ │ │ │ └── profile/
│ │ │ │ └── api/ # API route handlers
│ │ │ │ ├── auth/[...nextauth]/route.ts
│ │ │ │ └── webhooks/
│ │ │ ├── components/
│ │ │ │ ├── ui/ # Shadcn components
│ │ │ │ ├── layout/
│ │ │ │ │ ├── Navigation.tsx
│ │ │ │ │ ├── Footer.tsx
│ │ │ │ │ └── ThemeSwitcher.tsx
│ │ │ │ ├── home/
│ │ │ │ ├── charter/
│ │ │ │ ├── maintenance/
│ │ │ │ └── shared/
│ │ │ ├── lib/
│ │ │ │ ├── auth/ # Keycloak integration
│ │ │ │ ├── db/ # Supabase client
│ │ │ │ ├── api/ # API client
│ │ │ │ ├── stripe/ # Payment processing
│ │ │ │ └── utils/
│ │ │ ├── hooks/
│ │ │ ├── styles/
│ │ │ │ └── globals.css
│ │ │ └── types/
│ │ ├── public/
│ │ │ ├── images/
│ │ │ └── fonts/
│ │ ├── Dockerfile
│ │ ├── next.config.js
│ │ ├── tailwind.config.js
│ │ ├── tsconfig.json
│ │ └── package.json
│ │
│ └── api/ # API Gateway
│ ├── src/
│ │ ├── server.ts # Main server file
│ │ ├── routes/
│ │ │ ├── index.ts
│ │ │ ├── charter.routes.ts
│ │ │ ├── maintenance.routes.ts
│ │ │ ├── payment.routes.ts
│ │ │ └── user.routes.ts
│ │ ├── middleware/
│ │ │ ├── auth.middleware.ts
│ │ │ ├── cors.middleware.ts
│ │ │ ├── rate-limit.middleware.ts
│ │ │ └── validation.middleware.ts
│ │ ├── services/
│ │ │ ├── service.discovery.ts
│ │ │ └── circuit-breaker.ts
│ │ └── utils/
│ ├── Dockerfile
│ ├── tsconfig.json
│ └── package.json
├── services/ # Microservices
│ ├── charter/
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── controllers/
│ │ │ ├── models/
│ │ │ ├── repositories/
│ │ │ └── services/
│ │ ├── tests/
│ │ ├── Dockerfile
│ │ └── package.json
│ │
│ ├── maintenance/
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── controllers/
│ │ │ ├── models/
│ │ │ ├── repositories/
│ │ │ └── services/
│ │ ├── tests/
│ │ ├── Dockerfile
│ │ └── package.json
│ │
│ ├── payments/
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── stripe/
│ │ │ ├── invoice-ninja/
│ │ │ └── webhooks/
│ │ ├── Dockerfile
│ │ └── package.json
│ │
│ └── notifications/
│ ├── src/
│ │ ├── index.ts
│ │ ├── email/
│ │ ├── sms/
│ │ └── templates/
│ ├── Dockerfile
│ └── package.json
├── packages/ # Shared packages (monorepo)
│ ├── types/ # TypeScript type definitions
│ │ ├── src/
│ │ │ ├── models.ts
│ │ │ ├── api.ts
│ │ │ └── enums.ts
│ │ └── package.json
│ │
│ ├── utils/ # Shared utilities
│ │ ├── src/
│ │ │ ├── dates.ts
│ │ │ ├── validation.ts
│ │ │ └── formatters.ts
│ │ └── package.json
│ │
│ └── config/ # Shared configurations
│ ├── src/
│ │ ├── theme.ts
│ │ ├── constants.ts
│ │ └── api-routes.ts
│ └── package.json
├── migrations/ # Database migrations
│ ├── 001_initial_schema.sql
│ ├── 002_create_organizations.sql
│ ├── 003_create_users.sql
│ ├── 004_create_vessels.sql
│ ├── 005_create_bookings.sql
│ ├── 006_create_services.sql
│ ├── 007_create_invoices.sql
│ └── seed_data.sql
└── scripts/ # Utility scripts
├── setup.sh # Initial project setup
├── migrate-mockups.js # Convert HTML mockups to React
├── seed-database.js # Populate with demo data
└── deploy.sh # Deployment script
```
---
## 🗄️ Database Architecture
### Multi-Tenant Strategy: Row-Level Security with Shared Database
```sql
-- Core schema design
CREATE SCHEMA IF NOT EXISTS public;
CREATE SCHEMA IF NOT EXISTS maintenance;
CREATE SCHEMA IF NOT EXISTS charter;
-- Organizations table (tenants)
CREATE TABLE public.organizations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(255) NOT NULL,
type VARCHAR(20) CHECK (type IN ('maintenance', 'charter', 'both')),
subscription_tier VARCHAR(50) DEFAULT 'basic',
settings JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Users table with organization relationship
CREATE TABLE public.users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
email VARCHAR(255) UNIQUE NOT NULL,
keycloak_id VARCHAR(255) UNIQUE,
role VARCHAR(50) NOT NULL,
profile JSONB DEFAULT '{}',
preferences JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Vessels table
CREATE TABLE public.vessels (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
name VARCHAR(255) NOT NULL,
type VARCHAR(50),
make VARCHAR(100),
model VARCHAR(100),
year INTEGER,
length_ft DECIMAL(5,2),
capacity INTEGER,
specifications JSONB DEFAULT '{}',
health_score INTEGER DEFAULT 100,
status VARCHAR(50) DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Charter bookings
CREATE TABLE charter.bookings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
vessel_id UUID REFERENCES public.vessels(id),
user_id UUID REFERENCES public.users(id),
booking_date DATE NOT NULL,
start_time TIME NOT NULL,
duration_hours INTEGER NOT NULL,
guest_count INTEGER NOT NULL,
total_price DECIMAL(10,2),
status VARCHAR(50) DEFAULT 'pending',
payment_intent_id VARCHAR(255),
special_requests TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Maintenance work orders
CREATE TABLE maintenance.work_orders (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
vessel_id UUID REFERENCES public.vessels(id),
user_id UUID REFERENCES public.users(id),
service_type VARCHAR(100) NOT NULL,
priority VARCHAR(20) CHECK (priority IN ('emergency', 'urgent', 'routine')),
scheduled_date DATE,
description TEXT,
status VARCHAR(50) DEFAULT 'pending',
estimated_cost DECIMAL(10,2),
actual_cost DECIMAL(10,2),
technician_notes TEXT,
completed_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Documents table
CREATE TABLE public.documents (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
entity_type VARCHAR(50) NOT NULL,
entity_id UUID NOT NULL,
name VARCHAR(255) NOT NULL,
type VARCHAR(100),
s3_key VARCHAR(500) NOT NULL,
size_bytes BIGINT,
metadata JSONB DEFAULT '{}',
uploaded_by UUID REFERENCES public.users(id),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Invoices table
CREATE TABLE public.invoices (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID REFERENCES public.organizations(id),
invoice_number VARCHAR(50) UNIQUE NOT NULL,
type VARCHAR(20) CHECK (type IN ('charter', 'maintenance')),
booking_id UUID,
work_order_id UUID,
amount DECIMAL(10,2) NOT NULL,
status VARCHAR(50) DEFAULT 'pending',
invoice_ninja_id VARCHAR(255),
due_date DATE,
paid_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Enable Row Level Security
ALTER TABLE public.organizations ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.vessels ENABLE ROW LEVEL SECURITY;
ALTER TABLE charter.bookings ENABLE ROW LEVEL SECURITY;
ALTER TABLE maintenance.work_orders ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.documents ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.invoices ENABLE ROW LEVEL SECURITY;
-- Create RLS policies
CREATE POLICY tenant_isolation_organizations ON public.organizations
USING (id = current_setting('app.current_organization')::UUID);
CREATE POLICY tenant_isolation_users ON public.users
USING (organization_id = current_setting('app.current_organization')::UUID);
CREATE POLICY tenant_isolation_vessels ON public.vessels
USING (organization_id = current_setting('app.current_organization')::UUID);
-- Indexes for performance
CREATE INDEX idx_vessels_org_id ON public.vessels(organization_id);
CREATE INDEX idx_bookings_date ON charter.bookings(booking_date);
CREATE INDEX idx_work_orders_status ON maintenance.work_orders(status);
CREATE INDEX idx_invoices_status ON public.invoices(status);
CREATE INDEX idx_documents_entity ON public.documents(entity_type, entity_id);
```
---
## 🔌 API Design
### RESTful API Endpoints
```typescript
// API Routes Structure
const API_ROUTES = {
// Authentication
'POST /api/auth/login': 'User login with Keycloak',
'POST /api/auth/logout': 'User logout',
'POST /api/auth/refresh': 'Refresh JWT token',
'GET /api/auth/me': 'Get current user',
// Organizations
'GET /api/organizations/:id': 'Get organization details',
'PUT /api/organizations/:id': 'Update organization',
'GET /api/organizations/:id/users': 'List organization users',
// Vessels
'GET /api/vessels': 'List vessels',
'POST /api/vessels': 'Create vessel',
'GET /api/vessels/:id': 'Get vessel details',
'PUT /api/vessels/:id': 'Update vessel',
'DELETE /api/vessels/:id': 'Delete vessel',
// Charter Service
'GET /api/charter/availability': 'Check vessel availability',
'GET /api/charter/bookings': 'List bookings',
'POST /api/charter/bookings': 'Create booking',
'GET /api/charter/bookings/:id': 'Get booking details',
'PUT /api/charter/bookings/:id': 'Update booking',
'POST /api/charter/bookings/:id/cancel': 'Cancel booking',
'GET /api/charter/packages': 'List available packages',
'POST /api/charter/calculate-price': 'Calculate booking price',
// Maintenance Service
'GET /api/maintenance/services': 'List available services',
'GET /api/maintenance/work-orders': 'List work orders',
'POST /api/maintenance/work-orders': 'Create work order',
'GET /api/maintenance/work-orders/:id': 'Get work order details',
'PUT /api/maintenance/work-orders/:id': 'Update work order',
'GET /api/maintenance/schedule': 'Get maintenance schedule',
'POST /api/maintenance/schedule': 'Schedule maintenance',
// Payments
'POST /api/payments/create-intent': 'Create Stripe payment intent',
'POST /api/payments/confirm': 'Confirm payment',
'GET /api/payments/history': 'Get payment history',
'POST /api/payments/refund': 'Process refund',
// Invoices
'GET /api/invoices': 'List invoices',
'GET /api/invoices/:id': 'Get invoice details',
'POST /api/invoices/:id/pay': 'Pay invoice',
'GET /api/invoices/:id/download': 'Download invoice PDF',
// Documents
'GET /api/documents': 'List documents',
'POST /api/documents/upload': 'Upload document',
'GET /api/documents/:id': 'Get document',
'DELETE /api/documents/:id': 'Delete document',
// Notifications
'POST /api/notifications/email': 'Send email notification',
'GET /api/notifications/preferences': 'Get notification preferences',
'PUT /api/notifications/preferences': 'Update preferences',
// Reports & Analytics
'GET /api/analytics/dashboard': 'Dashboard metrics',
'GET /api/analytics/revenue': 'Revenue reports',
'GET /api/analytics/utilization': 'Vessel utilization'
};
```
---
## 🐳 Docker Configuration
### Complete docker-compose.yml
```yaml
version: '3.9'
networks:
harborsmith:
driver: bridge
volumes:
postgres_data:
minio_data:
keycloak_data:
directus_uploads:
redis_data:
services:
# ===== FRONTEND =====
web:
build:
context: ./apps/web
dockerfile: Dockerfile
args:
- NODE_ENV=production
container_name: harborsmith-web
restart: unless-stopped
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- NEXT_PUBLIC_API_URL=http://api:4000
- NEXT_PUBLIC_SUPABASE_URL=${SUPABASE_URL}
- NEXT_PUBLIC_SUPABASE_ANON_KEY=${SUPABASE_ANON_KEY}
- NEXT_PUBLIC_STRIPE_PUBLIC_KEY=${STRIPE_PUBLIC_KEY}
- NEXT_PUBLIC_KEYCLOAK_URL=http://keycloak:8080
- NEXT_PUBLIC_KEYCLOAK_REALM=harborsmith
- NEXT_PUBLIC_KEYCLOAK_CLIENT_ID=harborsmith-web
depends_on:
- api
- keycloak
networks:
- harborsmith
# ===== API GATEWAY =====
api:
build:
context: ./apps/api
dockerfile: Dockerfile
container_name: harborsmith-api
restart: unless-stopped
ports:
- "4000:4000"
environment:
- NODE_ENV=production
- PORT=4000
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/harborsmith
- REDIS_URL=redis://redis:6379
- KEYCLOAK_URL=http://keycloak:8080
- KEYCLOAK_REALM=harborsmith
- KEYCLOAK_CLIENT_ID=harborsmith-api
- KEYCLOAK_CLIENT_SECRET=${KEYCLOAK_CLIENT_SECRET}
- JWT_SECRET=${JWT_SECRET}
- CHARTER_SERVICE_URL=http://charter-service:5001
- MAINTENANCE_SERVICE_URL=http://maintenance-service:5002
- PAYMENT_SERVICE_URL=http://payment-service:5003
- NOTIFICATION_SERVICE_URL=http://notification-service:5004
depends_on:
- postgres
- redis
- keycloak
networks:
- harborsmith
# ===== MICROSERVICES =====
charter-service:
build:
context: ./services/charter
dockerfile: Dockerfile
container_name: harborsmith-charter
restart: unless-stopped
ports:
- "5001:5001"
environment:
- NODE_ENV=production
- PORT=5001
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/harborsmith
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
networks:
- harborsmith
maintenance-service:
build:
context: ./services/maintenance
dockerfile: Dockerfile
container_name: harborsmith-maintenance
restart: unless-stopped
ports:
- "5002:5002"
environment:
- NODE_ENV=production
- PORT=5002
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/harborsmith
- REDIS_URL=redis://redis:6379
depends_on:
- postgres
- redis
networks:
- harborsmith
payment-service:
build:
context: ./services/payments
dockerfile: Dockerfile
container_name: harborsmith-payments
restart: unless-stopped
ports:
- "5003:5003"
environment:
- NODE_ENV=production
- PORT=5003
- STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY}
- STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET}
- INVOICE_NINJA_URL=${INVOICE_NINJA_URL}
- INVOICE_NINJA_TOKEN=${INVOICE_NINJA_TOKEN}
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/harborsmith
depends_on:
- postgres
networks:
- harborsmith
notification-service:
build:
context: ./services/notifications
dockerfile: Dockerfile
container_name: harborsmith-notifications
restart: unless-stopped
ports:
- "5004:5004"
environment:
- NODE_ENV=production
- PORT=5004
- SMTP_HOST=${POSTE_HOST}
- SMTP_PORT=${POSTE_PORT}
- SMTP_SECURE=${POSTE_SECURE}
- SMTP_USER=${POSTE_USER}
- SMTP_PASS=${POSTE_PASS}
- LISTMONK_URL=${LISTMONK_URL}
- LISTMONK_USER=${LISTMONK_USER}
- LISTMONK_PASS=${LISTMONK_PASS}
networks:
- harborsmith
# ===== DATABASES & STORAGE =====
postgres:
image: supabase/postgres:15.1.0.117
container_name: harborsmith-db
restart: unless-stopped
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=harborsmith
volumes:
- postgres_data:/var/lib/postgresql/data
- ./migrations:/docker-entrypoint-initdb.d:ro
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
networks:
- harborsmith
redis:
image: redis:7-alpine
container_name: harborsmith-redis
restart: unless-stopped
ports:
- "6379:6379"
volumes:
- redis_data:/data
command: redis-server --appendonly yes
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- harborsmith
# ===== AUTHENTICATION =====
keycloak:
image: quay.io/keycloak/keycloak:23.0
container_name: harborsmith-keycloak
restart: unless-stopped
ports:
- "8080:8080"
environment:
- KEYCLOAK_ADMIN=${KEYCLOAK_ADMIN}
- KEYCLOAK_ADMIN_PASSWORD=${KEYCLOAK_ADMIN_PASSWORD}
- KC_DB=postgres
- KC_DB_URL=jdbc:postgresql://postgres:5432/keycloak
- KC_DB_USERNAME=postgres
- KC_DB_PASSWORD=${POSTGRES_PASSWORD}
- KC_HOSTNAME_STRICT=false
- KC_HTTP_ENABLED=true
- KC_HEALTH_ENABLED=true
command: start-dev
volumes:
- keycloak_data:/opt/keycloak/data
depends_on:
- postgres
networks:
- harborsmith
# ===== FILE STORAGE =====
minio:
image: minio/minio:latest
container_name: harborsmith-minio
restart: unless-stopped
ports:
- "9000:9000"
- "9001:9001"
environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- MINIO_BROWSER_REDIRECT_URL=http://localhost:9001
volumes:
- minio_data:/data
command: server /data --console-address ":9001"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
networks:
- harborsmith
createbuckets:
image: minio/mc:latest
container_name: harborsmith-minio-setup
depends_on:
- minio
entrypoint: >
/bin/sh -c "
/usr/bin/mc config host add harborsmith http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD};
/usr/bin/mc mb harborsmith/documents;
/usr/bin/mc mb harborsmith/images;
/usr/bin/mc mb harborsmith/directus;
/usr/bin/mc policy set public harborsmith/images;
exit 0;
"
networks:
- harborsmith
# ===== CMS =====
directus:
image: directus/directus:10.8
container_name: harborsmith-cms
restart: unless-stopped
ports:
- "8055:8055"
environment:
- KEY=${DIRECTUS_KEY}
- SECRET=${DIRECTUS_SECRET}
- DB_CLIENT=pg
- DB_HOST=postgres
- DB_PORT=5432
- DB_DATABASE=directus
- DB_USER=postgres
- DB_PASSWORD=${POSTGRES_PASSWORD}
- ADMIN_EMAIL=${DIRECTUS_ADMIN_EMAIL}
- ADMIN_PASSWORD=${DIRECTUS_ADMIN_PASSWORD}
- PUBLIC_URL=http://localhost:8055
- STORAGE_LOCATIONS=s3
- STORAGE_S3_DRIVER=s3
- STORAGE_S3_ENDPOINT=http://minio:9000
- STORAGE_S3_BUCKET=directus
- STORAGE_S3_REGION=us-east-1
- STORAGE_S3_KEY=${MINIO_ROOT_USER}
- STORAGE_S3_SECRET=${MINIO_ROOT_PASSWORD}
volumes:
- directus_uploads:/directus/uploads
depends_on:
- postgres
- minio
networks:
- harborsmith
# ===== ANALYTICS =====
umami:
image: ghcr.io/umami-software/umami:postgresql-latest
container_name: harborsmith-analytics
restart: unless-stopped
ports:
- "3001:3000"
environment:
- DATABASE_URL=postgresql://postgres:${POSTGRES_PASSWORD}@postgres:5432/umami
- DATABASE_TYPE=postgresql
- HASH_SALT=${UMAMI_HASH_SALT}
- TRACKER_SCRIPT_NAME=script.js
- DISABLE_UPDATES=true
depends_on:
- postgres
networks:
- harborsmith
```
---
## 🔄 Migration Strategy: Mockups to Production
### Phase 1: Component Extraction (Days 1-3)
#### 1. Extract Design System
```javascript
// scripts/migrate-mockups.js
const fs = require('fs');
const path = require('path');
const cheerio = require('cheerio');
// Extract colors, fonts, and styles from existing CSS
const extractDesignTokens = () => {
const cssFiles = [
'website-mockups/css/styles.css',
'website-mockups/css/themes.css',
'website-mockups/css/voyage-layout.css'
];
// Parse CSS and generate Tailwind config
// Extract color variables
// Extract font definitions
// Generate component classes
};
// Convert HTML components to React
const convertToReact = (htmlFile) => {
const html = fs.readFileSync(htmlFile, 'utf8');
const $ = cheerio.load(html);
// Extract components
const navigation = $('.voyage-nav').html();
const hero = $('.hero-voyage').html();
const footer = $('.voyage-footer').html();
// Generate React components
// Handle event listeners
// Convert class names to Tailwind
// Extract inline styles
};
```
#### 2. Component Mapping
```typescript
// Component extraction map
interface ComponentMap {
source: string; // HTML file location
target: string; // React component location
dependencies: string[]; // Required components
data: string[]; // Required data/props
}
const componentMappings: ComponentMap[] = [
{
source: 'website-mockups/index.html',
target: 'apps/web/src/components/home/Hero.tsx',
dependencies: ['Button', 'Container'],
data: ['heroTitle', 'heroSubtitle', 'ctaText']
},
{
source: 'website-mockups/charter.html',
target: 'apps/web/src/components/charter/FleetGrid.tsx',
dependencies: ['Card', 'Badge', 'Image'],
data: ['vessels', 'pricing', 'availability']
},
// ... more mappings
];
```
### Phase 2: React Component Generation (Days 4-7)
#### Example: Hero Component
```typescript
// apps/web/src/components/home/Hero.tsx
'use client';
import { motion } from 'framer-motion';
import { ArrowRight, Anchor } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { useTheme } from '@/hooks/useTheme';
import Link from 'next/link';
export const Hero = () => {
const { theme } = useTheme();
return (
<section className="relative min-h-screen flex items-center">
{/* Background gradient from mockup */}
<div className="absolute inset-0 bg-gradient-to-br from-[#001f3f] via-[#003366] to-[#001f3f]" />
{/* Wave animation from original */}
<div className="absolute bottom-0 left-0 right-0">
<svg viewBox="0 0 1440 320" className="w-full">
<motion.path
fill="rgba(255,255,255,0.1)"
d="M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,112C672,96,768,96,864,112C960,128,1056,160,1152,165.3C1248,171,1344,149,1392,138.7L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
animate={{
d: [
"M0,96L48,112C96,128,192,160,288,160C384,160,480,128,576,112C672,96,768,96,864,112C960,128,1056,160,1152,165.3C1248,171,1344,149,1392,138.7L1440,128L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z",
"M0,128L48,138.7C96,149,192,171,288,165.3C384,160,480,128,576,112C672,96,768,96,864,112C960,128,1056,160,1152,160C1248,160,1344,128,1392,112L1440,96L1440,320L1392,320C1344,320,1248,320,1152,320C1056,320,960,320,864,320C768,320,672,320,576,320C480,320,384,320,288,320C192,320,96,320,48,320L0,320Z"
]
}}
transition={{
repeat: Infinity,
repeatType: "reverse",
duration: 10,
ease: "easeInOut"
}}
/>
</svg>
</div>
{/* Content */}
<div className="container mx-auto px-4 relative z-10">
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
className="max-w-4xl mx-auto text-center text-white"
>
<motion.div
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{ delay: 0.2, type: "spring" }}
className="inline-flex items-center gap-2 mb-6 px-4 py-2 bg-white/10 backdrop-blur rounded-full"
>
<Anchor className="w-5 h-5" />
<span className="text-sm font-medium">San Francisco Bay's Premier Yacht Services</span>
</motion.div>
<h1 className="font-display text-5xl md:text-7xl font-bold mb-6">
Your Journey Begins at{' '}
<span className="bg-gradient-to-r from-[#dc143c] to-[#ef4444] bg-clip-text text-transparent">
HarborSmith
</span>
</h1>
<p className="text-xl md:text-2xl mb-8 text-white/90">
Experience luxury yacht charters and professional maintenance services
with San Francisco's most trusted maritime partner
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
asChild
size="lg"
className="bg-gradient-to-r from-[#dc143c] to-[#ef4444] hover:from-[#b91c3c] hover:to-[#dc143c]"
>
<Link href="/charter">
Explore Charters
<ArrowRight className="ml-2 w-5 h-5" />
</Link>
</Button>
<Button
asChild
size="lg"
variant="outline"
className="border-white text-white hover:bg-white hover:text-[#001f3f]"
>
<Link href="/maintenance">
Maintenance Services
</Link>
</Button>
</div>
</motion.div>
</div>
</section>
);
};
```
---
## 📅 Implementation Timeline
### Week 1: Infrastructure & Foundation
#### Day 1-2: Project Setup
- [ ] Initialize Git repository
- [ ] Set up monorepo with pnpm workspaces
- [ ] Configure Docker environments (dev/prod)
- [ ] Set up environment variables
- [ ] Initialize Next.js with TypeScript
- [ ] Configure ESLint and Prettier
#### Day 3-4: Database & Auth
- [ ] Deploy PostgreSQL with Supabase
- [ ] Run initial migrations
- [ ] Configure Keycloak realm
- [ ] Set up SSO clients
- [ ] Test authentication flow
- [ ] Configure Row Level Security
#### Day 5: Services Setup
- [ ] Create API Gateway structure
- [ ] Initialize microservices
- [ ] Set up service discovery
- [ ] Configure Redis caching
- [ ] Set up MinIO buckets
- [ ] Deploy Directus CMS
### Week 2: Core Application
#### Day 6-7: Frontend Foundation
- [ ] Convert mockup styles to Tailwind
- [ ] Create component library
- [ ] Implement theme system
- [ ] Set up routing structure
- [ ] Create layout components
- [ ] Implement navigation
#### Day 8-9: Public Pages
- [ ] Homepage with all sections
- [ ] Charter service pages
- [ ] Maintenance service pages
- [ ] About page
- [ ] Contact page
- [ ] FAQ page
#### Day 10: Authentication Integration
- [ ] Keycloak provider setup
- [ ] Login/Register flows
- [ ] Protected routes
- [ ] Role-based access
- [ ] Session management
- [ ] Logout functionality
### Week 3: Portal Development
#### Day 11-12: User Dashboard
- [ ] Dashboard layout
- [ ] Charter dashboard widgets
- [ ] Maintenance dashboard widgets
- [ ] Activity timeline
- [ ] Quick actions
- [ ] Notifications panel
#### Day 13-14: Booking Systems
- [ ] Charter booking wizard
- [ ] Maintenance scheduling
- [ ] Calendar integration
- [ ] Availability checking
- [ ] Price calculation
- [ ] Booking confirmation
#### Day 15: Document Management
- [ ] File upload to MinIO
- [ ] Document viewer
- [ ] Document categorization
- [ ] Download functionality
- [ ] Document sharing
- [ ] Version control
### Week 4: Integration & Launch
#### Day 16-17: Payment & Invoicing
- [ ] Stripe integration
- [ ] Payment intents
- [ ] InvoiceNinja API
- [ ] Invoice generation
- [ ] Payment history
- [ ] Refund processing
#### Day 18-19: Testing & Optimization
- [ ] End-to-end testing
- [ ] Performance optimization
- [ ] Security audit
- [ ] Load testing
- [ ] Bug fixes
- [ ] Mobile optimization
#### Day 20: Deployment
- [ ] Production configuration
- [ ] SSL certificates
- [ ] DNS configuration
- [ ] Monitoring setup
- [ ] Backup configuration
- [ ] Go-live checklist
---
## 🚀 Quick Start Guide
### Prerequisites
```bash
# Required software
- Node.js 20+
- Docker & Docker Compose
- pnpm (npm install -g pnpm)
- Git
```
### Initial Setup
```bash
# 1. Clone the repository
git clone [repository-url]
cd harborsmith-platform
# 2. Install dependencies
pnpm install
# 3. Set up environment variables
cp .env.example .env
# Edit .env with your configuration
# 4. Start Docker services
docker-compose up -d
# 5. Run database migrations
docker exec harborsmith-db psql -U postgres -d harborsmith -f /docker-entrypoint-initdb.d/001_initial_schema.sql
docker exec harborsmith-db psql -U postgres -d harborsmith -f /docker-entrypoint-initdb.d/002_create_organizations.sql
# ... run all migrations
# 6. Seed demo data
pnpm run seed
# 7. Start development servers
pnpm run dev
# 8. Convert mockups to React components
pnpm run migrate:mockups
```
### Access Points
```
Frontend: http://localhost:3000
API Gateway: http://localhost:4000
Keycloak: http://localhost:8080
Directus CMS: http://localhost:8055
MinIO Console: http://localhost:9001
Umami Analytics: http://localhost:3001
```
### Development Commands
```bash
# Start all services
pnpm run dev
# Run tests
pnpm run test
# Build for production
pnpm run build
# Deploy to production
pnpm run deploy
# Generate API documentation
pnpm run docs:api
# Run database migrations
pnpm run db:migrate
# Seed database
pnpm run db:seed
# Format code
pnpm run format
# Lint code
pnpm run lint
```
---
## 🎯 Critical Path to MVP
### Must-Have Features (Week 1-2)
1. **User Authentication**
- Login/Register with Keycloak
- Role-based access (Customer, Admin, Service Provider)
- Session management
2. **Core Booking Flow**
- Browse available services
- Select yacht/service
- Choose date/time
- Complete payment
- Receive confirmation
3. **Basic Dashboard**
- View bookings
- Manage vessels
- View invoices
- Upload documents
### Should-Have Features (Week 3)
1. **Communication**
- Email notifications
- Booking confirmations
- Reminder emails
2. **Payment Processing**
- Stripe integration
- Invoice generation
- Payment history
3. **Admin Panel**
- Manage users
- View all bookings
- Generate reports
### Nice-to-Have Features (Week 4+)
1. **Advanced Features**
- Real-time availability
- Dynamic pricing
- Weather integration
- Route planning
2. **Analytics**
- Revenue tracking
- Utilization reports
- Customer insights
---
## 🔒 Security Considerations
### Authentication & Authorization
- Keycloak SSO with MFA support
- JWT tokens with refresh mechanism
- Role-based access control (RBAC)
- API key management for services
### Data Protection
- TLS/SSL for all communications
- Encryption at rest (database)
- Encryption in transit
- PII data isolation
- GDPR compliance measures
### Infrastructure Security
- Container security scanning
- Regular dependency updates
- Rate limiting on APIs
- DDoS protection
- Regular security audits
---
## 📊 Performance Targets
### Frontend Performance
```yaml
Metrics:
First Contentful Paint: < 1.5s
Time to Interactive: < 3.5s
Cumulative Layout Shift: < 0.1
Largest Contentful Paint: < 2.5s
Optimization:
- Next.js ISR for static content
- Image optimization with next/image
- Code splitting per route
- Lazy loading components
- CDN for static assets
```
### Backend Performance
```yaml
API Response Times:
GET endpoints: < 200ms (p95)
POST endpoints: < 300ms (p95)
Database queries: < 50ms (p95)
Optimization:
- Redis caching layer
- Database query optimization
- Connection pooling
- Horizontal scaling ready
```
---
## 🚨 Monitoring & Alerts
### Application Monitoring
- Umami Analytics for user behavior
- Custom dashboards for business metrics
- Error tracking with Sentry (optional)
- Performance monitoring
### Infrastructure Monitoring
- Container health checks
- Database performance metrics
- API response times
- Resource utilization
### Alerting Rules
- Downtime > 1 minute
- Error rate > 1%
- Response time > 1s
- Database connection failures
- Payment processing failures
---
## 📝 Deployment Checklist
### Pre-Deployment
- [ ] All tests passing
- [ ] Security audit complete
- [ ] Performance benchmarks met
- [ ] Documentation updated
- [ ] Environment variables configured
- [ ] SSL certificates ready
### Deployment Steps
- [ ] Backup existing data
- [ ] Deploy database migrations
- [ ] Deploy backend services
- [ ] Deploy frontend application
- [ ] Verify all services running
- [ ] Run smoke tests
### Post-Deployment
- [ ] Monitor error rates
- [ ] Check performance metrics
- [ ] Verify email delivery
- [ ] Test payment processing
- [ ] Update DNS records
- [ ] Announce go-live
---
## 🤝 Team Collaboration
### Git Workflow
```bash
main
├── develop
│ ├── feature/user-authentication
│ ├── feature/booking-system
│ └── feature/payment-integration
├── staging
└── production
```
### Code Review Process
1. Create feature branch from develop
2. Implement feature with tests
3. Create pull request
4. Automated tests run
5. Code review by team
6. Merge to develop
7. Deploy to staging
8. Test in staging
9. Merge to main
10. Deploy to production
---
## 📚 Additional Resources
### Documentation
- API Documentation: `/docs/API_DOCUMENTATION.md`
- Deployment Guide: `/docs/DEPLOYMENT_GUIDE.md`
- Contributing Guide: `/docs/CONTRIBUTING.md`
- Security Policy: `/docs/SECURITY.md`
### External Resources
- [Next.js Documentation](https://nextjs.org/docs)
- [Supabase Documentation](https://supabase.io/docs)
- [Keycloak Documentation](https://www.keycloak.org/documentation)
- [Docker Documentation](https://docs.docker.com)
- [Stripe Documentation](https://stripe.com/docs)
### Support
- Technical Issues: Create GitHub issue
- Security Issues: security@harborsmith.com
- Business Inquiries: business@harborsmith.com
---
## 🎯 Success Metrics
### Technical Metrics
- 99.9% uptime
- < 3s page load time
- < 300ms API response time
- Zero critical security vulnerabilities
### Business Metrics
- 500+ vessels onboarded (Year 1)
- 100+ service providers
- 1000+ monthly active users
- 15% month-over-month growth
---
## ✅ Conclusion
This implementation plan provides everything needed to build HarborSmith from the ground up:
1. **Modern Architecture**: Microservices, SSR, real-time capabilities
2. **Enterprise Security**: Keycloak SSO, RLS, encryption
3. **Scalable Infrastructure**: Docker, Redis, horizontal scaling ready
4. **Developer Experience**: TypeScript, hot reloading, automated testing
5. **Production Ready**: Monitoring, analytics, backup strategies
With this plan, you can start development immediately and have a production-ready MVP within 4 weeks.
**Next Steps:**
1. Set up development environment
2. Begin with Week 1 infrastructure tasks
3. Convert mockups to React components
4. Implement core booking flows
5. Deploy to staging for testing
6. Launch MVP to production
---
*This document is a living guide and should be updated as the project evolves.*