Carlos Eduardo Gatti Ferreira

Monorepo Structure

This document explains how the codebase is organized, why it’s structured this way, and how to navigate and extend it.

Overview

This is a monorepo — a single repository containing multiple applications and shared code. All code lives in one place, making it easier to:


Root Directory Structure

carlosgatti.com/
├── app/                    # Next.js App Router (Discart-me, QRACK)
├── pages/                  # Next.js Pages Router (Personal website)
├── src/                    # Shared source code
├── components/             # Root-level shared components
├── docs/                   # Documentation
├── public/                 # Static assets
├── styles/                 # Global styles
├── scripts/                # Build and utility scripts
├── constants/              # Shared constants
├── types/                  # Root-level TypeScript types
├── util/                   # Utility functions
├── package.json            # Dependencies and scripts
├── tsconfig.json           # TypeScript configuration
├── tailwind.config.js      # Tailwind CSS configuration
├── next.config.mjs         # Next.js configuration
└── README.md               # This file's parent

/app — App Router Applications

Purpose: Next.js 13+ App Router applications

Structure:

app/
├── discart-me/            # Discart-me marketplace app
│   ├── layout.tsx         # App-wide layout with auth provider
│   ├── page.tsx           # Landing page
│   ├── dashboard/
│   ├── items/
│   └── README.md          # App-specific documentation
├── qrack/                 # QRACK inventory app
│   ├── layout.tsx         # App-wide layout with auth provider
│   ├── page.tsx           # Landing page
│   ├── containers/
│   ├── scanner/
│   └── README.md          # App-specific documentation
└── layout.tsx             # Root layout (wraps all apps)

Key Points:

Conventions:


/pages — Pages Router (Legacy)

Purpose: Next.js Pages Router for the personal website

Structure:

pages/
├── _app.tsx               # App wrapper (providers, global styles)
├── _document.tsx          # HTML document customization
├── index.tsx              # Home page
├── about.tsx              # About page
├── blogs/                 # Blog posts (MDX)
│   ├── index.tsx          # Blog listing
│   └── {slug}/            # Individual blog posts
├── projects.tsx           # Projects showcase
└── api/                   # API routes
    ├── send-email.tsx     # Email sending endpoint
    └── generate-resume.ts # Resume PDF generation

Key Points:

Conventions:


/src — Shared Source Code

Purpose: Reusable code shared across all applications

Structure:

src/
├── components/            # Shared React components
│   ├── discart-me/       # Discart-me specific components
│   ├── qrack/            # QRACK specific components
│   ├── comments/         # Comments feature components
│   └── ratings/          # Ratings feature components
├── features/             # Feature modules
│   ├── auth/             # Authentication feature
│   │   ├── AuthProvider.tsx
│   │   ├── useAuth.ts
│   │   ├── providers/
│   │   └── hooks/
│   ├── discart-me/       # Discart-me features
│   │   └── hooks/
│   └── qrack/            # QRACK features
│       ├── components/
│       └── hooks/
├── lib/                  # Libraries and utilities
│   ├── api/              # API clients
│   │   └── core/         # Core API utilities
│   ├── image/            # Image processing library
│   ├── qrackApi.ts       # QRACK GraphQL client
│   ├── discartMeApi.ts   # Discart-me REST client
│   ├── boxhubApi.ts      # BoxHub GraphQL client
│   ├── upload.ts         # File upload helpers
│   └── utils.ts          # General utilities
├── hooks/                # Shared React hooks
│   ├── useComments.ts
│   ├── useRatings.ts
│   ├── useDebounce.ts
│   └── ...
├── context/              # React Context providers
│   ├── DiscartAuthContext.tsx
│   ├── QrackAuthContext.tsx
│   └── BoxHubAuthContext.tsx
├── graphql/              # GraphQL queries and mutations
│   ├── queries/
│   └── mutations/
├── types/                # Shared TypeScript types
└── constants/            # Shared constants

Key Points:

Conventions:


/components — Root-Level Components

Purpose: High-level layout and shared UI components

Structure:

components/
├── ui/                   # Generic UI primitives
│   ├── Button.tsx
│   ├── Input.tsx
│   ├── Modal.tsx
│   ├── Loading.tsx
│   └── index.ts
├── Navbar/               # Navigation components
├── Footer.tsx            # Site footer
├── Hero.tsx              # Hero sections
└── ...

Key Points:

Conventions:


/docs — Documentation

Purpose: All project documentation

Structure:

docs/
├── architecture.md           # System architecture
├── monorepo-structure.md     # This file
├── tech-stack.md             # Technologies used
├── conventions.md            # Coding conventions
├── decisions.md              # Architectural decisions
├── adr/                      # Architectural Decision Records
│   └── ADR-001-frontend-foundation-phase.md
├── analysis/                 # Analysis documents
│   └── IMAGE_UPLOAD_AUDIT.md
├── refactors/                # Refactoring documentation
│   ├── discart-me-image-processing.md
│   └── qrack-create-container.md
└── ui/                       # UI documentation
    └── UI_BASE_GUIDELINES.md

Conventions:


/public — Static Assets

Purpose: Files served statically (images, fonts, etc.)

Structure:

public/
├── blogs/                 # Blog images
├── discartme/             # Discart-me assets
├── qrack/                 # QRACK assets
├── boxhub/                # BoxHub assets
└── images/                # General images

Conventions:


Adding New Applications

Step 1: Create App Folder

app/
└── my-new-app/
    ├── layout.tsx
    ├── page.tsx
    └── README.md

Step 2: Add Layout with Providers

// app/my-new-app/layout.tsx
import { MyAppProvider } from '@/src/context/MyAppContext';

export default function MyAppLayout({ children }) {
  return (
    <MyAppProvider>
      {children}
    </MyAppProvider>
  );
}

Step 3: Create Domain-Specific Code

src/
├── components/
│   └── my-new-app/       # App-specific components
└── features/
    └── my-new-app/       # App-specific features

Step 4: Document

Create app/my-new-app/README.md explaining:


Adding New Packages/Features

Feature Module Structure

src/features/
└── my-feature/
    ├── components/        # Feature-specific UI
    ├── hooks/            # Feature-specific logic
    ├── types.ts          # Feature types
    └── README.md         # Feature documentation (if complex)

Shared Library Structure

src/lib/
└── my-library/
    ├── index.ts          # Public API
    ├── core.ts           # Core functionality
    ├── utils.ts          # Utilities
    └── types.ts          # Types

Guidelines:


Import Paths

Path Aliases

Configured in tsconfig.json:

{
  "paths": {
    "@/*": ["./*"],              // Root imports
    "@/src/*": ["./src/*"],      // Source code imports
    "@/components/*": ["./components/*"]
  }
}

Import Examples

// From root
import { Button } from '@/components/ui';

// From src
import { processImage } from '@/src/lib/image';
import { useAuth } from '@/src/features/auth/useAuth';

// Relative (within same feature)
import { MyComponent } from './components/MyComponent';

Conventions:


File Naming Conventions

Components

Utilities

Types

Hooks


Where Documentation Lives

Global Documentation

App Documentation

Feature Documentation


Future Considerations

Potential Reorganization

As the monorepo grows, consider:

  1. Workspace Packages — Move shared code to packages/ (if using npm workspaces)
  2. App Extraction — Extract apps to separate repos if they become too independent
  3. Turborepo — Add build system for parallel builds and caching

Current Approach

For now, the flat structure works well because: