# 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 (
{/* Background gradient from mockup */}
{/* Wave animation from original */}
{/* Content */}
San Francisco Bay's Premier Yacht Services

Your Journey Begins at{' '} HarborSmith

Experience luxury yacht charters and professional maintenance services with San Francisco's most trusted maritime partner

); }; ``` --- ## 📅 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.*