Complete guide to understanding ShipSafe's codebase organization and architecture.
Overview
ShipSafe follows a clean, domain-driven architecture that separates concerns and makes the codebase easy to navigate and extend. This guide explains the folder structure, conventions, and how different parts of the application work together.
Directory Structure
The ShipSafe project follows a clean, organized structure:
Root Directory:
src/- Source codeapp/- Next.js App Router (pages & routes)components/- React componentsfeatures/- Business logic moduleslib/- Utility libraries & integrationsmodels/- TypeScript type definitions
public/- Static assets (images, fonts, etc.)docs/- Documentationconfig.ts- Centralized app configurationtailwind.config.ts- TailwindCSS configurationnext.config.ts- Next.js configurationpackage.json- Dependencies
Core Directories
src/app/ - Next.js App Router
The App Router is the foundation of Next.js routing. Each folder represents a route.
Public Routes
src/app/
page.tsx- Landing page (/)auth/page.tsx- Authentication page (/auth)pricing/page.tsx- Pricing page (/pricing)privacy/page.tsx- Privacy policy (/privacy)terms/page.tsx- Terms of service (/terms)
Protected Routes
src/app/dashboard/
layout.tsx- Dashboard layout (requires auth)page.tsx- Main dashboard (/dashboard)billing/page.tsx- Billing page (/dashboard/billing)account/page.tsx- Account settings (/dashboard/account)
API Routes
src/app/api/
auth/- Authentication endpointslogin/route.ts- POST/api/auth/loginsignup/route.ts- POST/api/auth/signuplogout/route.ts- POST/api/auth/logoutreset/route.ts- POST/api/auth/reset
checkout/route.ts- POST/api/checkoutbilling/portal/route.ts- POST/api/billing/portalwebhooks/stripe/route.ts- POST/api/webhooks/stripe
Key Points:
- Each route folder contains a
route.tsfile with HTTP method handlers - API routes are server-side only
- Use
requireAuth()orgetCurrentUserServer()for authentication - All inputs validated with Zod schemas
Special Files
src/app/
layout.tsx- Root layout (wraps all pages)globals.css- Global styleserror.tsx- Error boundarynot-found.tsx- 404 pagefavicon.ico- Site favicon
src/components/ - React Components
Components are organized by type and purpose.
Template Components
src/components/templates/
Header.tsx- Site header/navigationHero.tsx- Hero sectionPricing.tsx- Pricing plansFAQ.tsx- FAQ sectionCTA.tsx- Call-to-action sectionFooter.tsx- Site footerTestimonial.tsx- Testimonials carouselProblem.tsx- Problem statementFeaturesGrid.tsx- Features gridFeaturesListicle.tsx- Feature showcase
Usage: Page-level components used on marketing/landing pages.
Rules:
- Should be reusable and customizable
- Accept props for content
- No business logic (use features/ instead)
- Can be Server or Client Components
UI Components
src/components/ui/
Button.tsx- Base button componentButtonCheckout.tsx- Stripe checkout buttonButtonSignin.tsx- Sign-in link buttonButtonGradient.tsx- Gradient button variantInput.tsx- Form input componentCard.tsx- Card containerBadge.tsx- Badge/label componentModal.tsx- Modal dialogLoader.tsx- Loading spinnerLogo.tsx- Logo componentBuiltWithShipSafe.tsx- Attribution badgeTestimonialsAvatars.tsx- Avatar display
Usage: Reusable UI primitives used throughout the app.
Rules:
- Highly reusable across different contexts
- Well-typed with TypeScript interfaces
- Accessible and semantic HTML
- DaisyUI classes for styling
Form Components
src/components/forms/
LoginForm.tsx- Login formSignupForm.tsx- Signup form
Usage: Form components with validation and error handling.
Rules:
- Client Components (use hooks for state)
- Include validation logic
- Handle loading and error states
- Integrate with API routes
Layout Components
src/components/layouts/
ClientLayout.tsx- Client-side layout wrapper
Usage: Layout wrappers for client-side features.
src/features/ - Business Logic
Features contain pure business logic, no React components.
Authentication Feature
src/features/auth/
login.ts- Login logicsignup.ts- Signup logiclogout.ts- Logout logicreset.ts- Password reset logicsend-reset.ts- Send reset emailschema.ts- Zod validation schemas
Key Functions:
signupUser()- Create new user accountloginUser()- Authenticate usersendPasswordResetEmail()- Send reset email- Validation schemas for all auth operations
Billing Feature
src/features/billing/
server.ts- Server-side billing operationswebhook.ts- Webhook event handlersschema.ts- Zod validation schemas
Key Functions:
createCheckoutSessionForUser()- Create Stripe checkoutgetUserSubscriptionStatus()- Get subscription infoupdateSubscriptionInFirestore()- Sync subscription- Webhook handlers for Stripe events
Rules:
- No React code (
.tsfiles only) - Server-side only (uses Admin SDK)
- Import from
lib/for utilities - Used by API routes, not components
src/lib/ - Utility Libraries
Core utilities and third-party integrations.
Firebase Integration
src/lib/firebase/
init.ts- Admin SDK initializationclient.ts- Client SDK initializationauth.ts- Auth helpers (server-side)admin.ts- Admin utilities
Key Functions:
getFirestoreInstance()- Get Firestore instancegetAuthInstance()- Get Auth instanceverifyAuth()- Verify authenticationrequireAuth()- Require authentication
Stripe Integration
src/lib/stripe/
client.ts- Stripe client initializationcheckout.ts- Checkout session creationbilling.ts- Billing portalwebhook.ts- Webhook signature verification
Key Functions:
getStripeClient()- Get Stripe instancecreateCheckoutSession()- Create checkoutparseWebhookEvent()- Verify webhooks
Security Utilities
src/lib/security/
env.ts- Environment variable helpersheaders.ts- Security headersrate_limit.ts- Rate limitingsecure_api.ts- API firewallcsrf.ts- CSRF protectionaudit.ts- Security audit logging
Rules:
- Server-side only
- Used by middleware
- Applied automatically to all routes
API Client
src/lib/
api.ts- Client-side API helpers
Key Functions:
apiGet(),apiPost(),apiPut(),apiDelete()- Automatic CSRF token handling
- Automatic auth token handling
- Error handling utilities
src/models/ - Type Definitions
TypeScript interfaces and type definitions.
src/models/
user.ts- User interface & Firestore converterssubscription.ts- Subscription interface & converterssubscription-status.ts- Subscription status enumplan.ts- Pricing plan interfaceroles.ts- User roles enum
Key Files:
user.ts- User model with Firestore converterssubscription.ts- Subscription model with convertersroles.ts- User role definitions
Rules:
- No business logic
- No React code
- Type definitions only
- Firestore converters for type safety
Configuration Files
config.ts - Central Configuration
Single source of truth for app configuration:
const config = {
appName: "ShipSafe",
domainName: "shipsafe.st",
stripe: {
plans: [/* ... */],
},
auth: {
loginUrl: "/auth",
callbackUrl: "/dashboard",
},
// ...
};
Usage: Import in components and API routes:
import config from "@/config";
Environment Variables
Store in .env.local (not committed to repo):
# Firebase
NEXT_PUBLIC_FIREBASE_API_KEY=...
FIREBASE_PROJECT_ID=...
# Stripe
STRIPE_SECRET_KEY=...
STRIPE_PUBLIC_KEY=...
See Environment Variables Guide.
Architecture Principles
1. Separation of Concerns
- Components - UI only, no business logic
- Features - Business logic, no UI
- Lib - Utilities and integrations
- Models - Type definitions only
2. Server Components by Default
- Use Server Components unless you need interactivity
- Client Components only when needed (
"use client") - Fetch data in Server Components when possible
3. Type Safety
- All functions typed with TypeScript
- Zod schemas for runtime validation
- Type inference from schemas
4. Security First
- All API routes protected by middleware
- Input validation on all endpoints
- Server-side authentication checks
- No sensitive data in client components
File Naming Conventions
Components
- PascalCase -
Button.tsx,LoginForm.tsx - Descriptive - Clear what component does
- Single responsibility - One purpose per component
Features
- camelCase -
login.ts,send-reset.ts - Domain-based - Grouped by feature area
- No React -
.tsfiles only
API Routes
- kebab-case -
route.tsfiles in folders - RESTful - Use HTTP methods correctly
- Single endpoint - One route.ts per endpoint
Import Patterns
Component Imports
// Absolute imports using @ alias
import Button from "@/components/ui/Button";
import Header from "@/components/templates/Header";
Feature Imports
// From features/
import { signupUser } from "@/features/auth/signup";
import { createCheckoutSession } from "@/features/billing/server";
Utility Imports
// From lib/
import { getFirestoreInstance } from "@/lib/firebase/init";
import { apiPost } from "@/lib/api";
Config Import
import config from "@/config";
Common Patterns
Creating a New Component
-
Create file in appropriate folder:
- UI component →
components/ui/ - Template component →
components/templates/ - Form component →
components/forms/
- UI component →
-
Add TypeScript interface for props
-
Export component as default
-
Add to component documentation
Creating a New API Route
- Create folder:
app/api/your-endpoint/ - Create
route.tswith handler functions - Add authentication if needed
- Add input validation with Zod
- Handle errors gracefully
Creating a New Feature
- Create folder:
features/your-feature/ - Add business logic files (
.tsonly) - Add Zod schemas for validation
- Import from
lib/for utilities - Use in API routes, not components
Learn More
- First Steps - Making your first changes
- Configuration Guide - Customizing settings
- Component Documentation - Component details
- Feature Documentation - Feature guides
Tips
- Follow the patterns - Existing code shows the way
- Keep it simple - Don't over-engineer
- Type everything - TypeScript catches errors early
- Read the comments - ShipSafe code is well-commented
- Check the docs - Component and feature docs have examples
Summary
Key Takeaways:
- ✅
app/- Routes and pages (Next.js App Router) - ✅
components/- UI components (organized by type) - ✅
features/- Business logic (no React) - ✅
lib/- Utilities and integrations - ✅
models/- Type definitions
Architecture:
- Separation of concerns
- Server Components by default
- Type-safe throughout
- Security-first approach
You now understand the ShipSafe codebase structure! 🎉