Global WatchGlobal Watch Docs
Architecture

Architecture Overview

Architecture Overview

Global Watch is built using modern software architecture principles that prioritize maintainability, testability, and scalability. This section covers the core architectural patterns and design decisions that shape the platform.

Core Principles

The Global Watch architecture is guided by several key principles:

  1. Separation of Concerns - Business logic is isolated from infrastructure
  2. Explicit Error Handling - Using Result types instead of exceptions
  3. Type Safety - Leveraging TypeScript for compile-time guarantees
  4. Security First - Row Level Security (RLS) at the database level
  5. Multi-Tenancy - Subdomain-based tenant isolation

Architecture Layers

┌─────────────────────────────────────────────────────────────────┐
│                     Presentation Layer                          │
│  Next.js App Router, React Server Components, Client Components │
├─────────────────────────────────────────────────────────────────┤
│                     Application Layer                           │
│  Commands, Queries, Use Cases, Server Actions                   │
├─────────────────────────────────────────────────────────────────┤
│                       Domain Layer                              │
│  Entities, Value Objects, Repository Interfaces (Ports)        │
├─────────────────────────────────────────────────────────────────┤
│                    Infrastructure Layer                         │
│  Supabase Adapters, External Services, Database                 │
└─────────────────────────────────────────────────────────────────┘

Directory Structure

The codebase follows a clear organizational structure:

apps/web/
├── app/                     # Next.js App Router pages
│   ├── (marketing)/         # Public marketing pages
│   ├── home/                # Personal account routes
│   ├── account/             # Team account routes
│   └── admin/               # Admin routes

├── core/                    # Business logic (Hexagonal)
│   ├── domain/              # Entities, Value Objects, Ports
│   ├── application/         # Commands, Queries, Strategies
│   └── shared/              # Result type, shared errors

└── infrastructure/          # External adapters
    └── database/supabase/   # Supabase implementations

Key Patterns

Hexagonal Architecture

Global Watch uses the Hexagonal Architecture (Ports & Adapters) pattern to isolate business logic from infrastructure concerns. This enables:

  • Testability - Domain logic can be tested without database
  • Flexibility - Infrastructure can be swapped without changing business logic
  • Clarity - Clear boundaries between layers

Learn more about Hexagonal Architecture →

Multi-Tenancy

The platform supports multiple tenants through subdomain-based routing:

  • Personal accounts - app.global.watch
  • Team accounts - {slug}.global.watch
  • Marketing - global.watch

Learn more about Multi-Tenancy →

Database Design

The database layer uses Supabase (PostgreSQL) with:

  • Row Level Security (RLS) - Authorization at the database level
  • Schema organization - Numbered schema files for migrations
  • Helper functions - Reusable access control functions

Learn more about Database Design →

Package Organization

Global Watch uses a monorepo structure with two package namespaces:

NamespacePurposeLocation
@kit/*Makerkit base packages (do not modify)packages/
@fw/*Global Watch custom packagespackages/fw/

@fw Packages

Custom Global Watch packages include:

  • @fw/ui - Custom UI components
  • @fw/accounts - Personal account features
  • @fw/team-accounts - Team account features
  • @fw/projects - Project management
  • @fw/entity-settings - Unified settings UI
  • @fw/versioning - Entity version history
  • @fw/audit - Audit logging

Result Type Pattern

Global Watch uses a Result type for explicit error handling:

type Result<T, E = Error> =
  | { ok: true; value: T }
  | { ok: false; error: E };

// Usage
const result = await repository.findById(id);

if (!result.ok) {
  // Handle error - TypeScript knows result.error exists
  return handleError(result.error);
}

// Success - TypeScript knows result.value exists
return result.value;

This pattern provides:

  • Explicit error handling - Errors must be handled
  • Type safety - TypeScript enforces correct usage
  • No exceptions - Predictable control flow

Technology Stack

CategoryTechnology
FrameworkNext.js 16 (App Router, Turbopack)
RuntimeReact 19, TypeScript 5.9+
DatabaseSupabase (PostgreSQL with RLS)
StylingTailwind CSS 4, Shadcn UI
MonorepoTurborepo with pnpm workspaces
Formsreact-hook-form + Zod validation
Data FetchingTanStack React Query (client), Supabase (server)
AuthSupabase Auth (email, OAuth, MFA)
BillingStripe
i18nreact-i18next

Next Steps

On this page