Project Structure - ThriveSend B2B2G
Project Structure - ThriveSend B2B2G
Section titled “Project Structure - ThriveSend B2B2G”Last Updated: October 22, 2025
Overview
Section titled “Overview”ThriveSend B2B2G follows Next.js 15 App Router conventions with a clear separation of concerns. The project is organized into distinct layers: presentation (app), components, business logic (lib/services), and data access (Prisma).
Root Directory Structure
Section titled “Root Directory Structure”thrive-send-b2b2g/├── src/ # Source code├── prisma/ # Database schema and migrations├── public/ # Static assets├── docs-new/ # Documentation (this site)├── e2e/ # Playwright end-to-end tests├── scripts/ # Utility scripts├── .github/ # GitHub Actions CI/CD├── .husky/ # Git hooks├── package.json # Project dependencies├── next.config.mjs # Next.js configuration├── tailwind.config.ts # Tailwind CSS configuration├── tsconfig.json # TypeScript configuration└── mkdocs.yml # Documentation site configurationSource Directory (src/)
Section titled “Source Directory (src/)”Complete Structure
Section titled “Complete Structure”src/├── app/ # Next.js 15 App Router│ ├── api/ # API Routes (92 endpoints)│ ├── (dashboard)/ # Dashboard pages (13 pages)│ ├── onboarding/ # Onboarding flow (4 pages)│ ├── invitations/ # Invitation acceptance│ ├── sign-in/ # Clerk authentication│ └── sign-up/ # Clerk registration├── components/ # React components (96+)│ ├── ui/ # Base UI components (46)│ ├── dashboard/ # Dashboard components (29)│ ├── analytics/ # Analytics components (6)│ ├── layout/ # Layout components (3)│ ├── auth/ # Auth components│ ├── compliance/ # Compliance components│ ├── consent/ # Consent management│ └── content/ # Content management├── lib/ # Utilities and services│ ├── services/ # Business logic (25 services)│ ├── constants/ # Application constants│ ├── middleware/ # Custom middleware│ ├── templates/ # Email templates│ ├── utils/ # Utility functions│ └── db.ts # Prisma client├── context/ # React Context providers│ └── ServiceProviderContext.tsx├── hooks/ # Custom React hooks│ └── use-service-provider.ts├── __tests__/ # Test files│ ├── api/ # API tests│ ├── compliance/ # Compliance tests│ ├── integration/ # Integration tests│ └── utils/ # Utility tests└── middleware.ts # Next.js middleware (Clerk auth)App Directory (src/app/)
Section titled “App Directory (src/app/)”The app directory follows Next.js 15 App Router conventions.
API Routes (src/app/api/)
Section titled “API Routes (src/app/api/)”All 92 REST API endpoints organized by domain:
src/app/api/├── analytics/ # Analytics API (7 endpoints)│ ├── route.ts # GET /api/analytics│ ├── dashboard/ # Dashboard metrics│ ├── performance/ # Performance data│ └── compliance/ # Compliance metrics├── campaigns/ # Campaign API (13 endpoints)│ ├── route.ts # GET/POST /api/campaigns│ ├── [campaignId]/ # Campaign CRUD│ ├── bulk/ # Bulk operations│ └── templates/ # Campaign templates├── clients/ # Client API (7 endpoints)│ ├── route.ts # GET/POST /api/clients│ └── [clientId]/ # Client CRUD├── compliance/ # Compliance API (4 endpoints)│ ├── alerts/ # Compliance alerts│ └── status/ # Compliance status├── content/ # Content API (11 endpoints)│ ├── route.ts # GET/POST /api/content│ ├── [contentId]/ # Content CRUD│ └── templates/ # Content templates├── team/ # Team API (6 endpoints)│ ├── route.ts # GET/POST /api/team│ └── [memberId]/ # Member operations├── service-provider/ # Service Provider API (9 endpoints)│ ├── route.ts # GET/POST /api/service-provider│ ├── organization/ # Organization CRUD│ ├── billing/ # Billing management│ ├── compliance/ # Compliance config│ └── security/ # Security config├── invitations/ # Invitation API (6 endpoints)│ ├── route.ts # GET/POST /api/invitations│ ├── accept/ # Accept invitation│ └── resend/ # Resend invitation├── audit/ # Audit Log API (3 endpoints)├── consent-preferences/ # Consent API (3 endpoints)├── data-subject-requests/ # POPIA DSR API (4 endpoints)├── webhooks/ # Webhook handlers│ ├── clerk/ # Clerk webhooks│ └── email/ # Email webhooks (Resend)├── health/ # Health check│ └── route.ts # GET /api/health└── __tests__/ # API testsScreenshot Placeholder:
Dashboard Pages (src/app/(dashboard)/)
Section titled “Dashboard Pages (src/app/(dashboard)/)”Protected dashboard routes (requires authentication):
src/app/(dashboard)/├── layout.tsx # Dashboard layout wrapper├── dashboard/ # Main dashboard│ └── page.tsx # /dashboard├── clients/ # Client management│ ├── page.tsx # /dashboard/clients│ └── [clientId]/ # /dashboard/clients/[id]│ └── page.tsx├── campaigns/ # Campaign management│ ├── page.tsx # /dashboard/campaigns│ ├── new/ # /dashboard/campaigns/new│ └── [campaignId]/ # /dashboard/campaigns/[id]│ └── page.tsx├── content/ # Content management│ ├── page.tsx # /dashboard/content│ └── [contentId]/ # /dashboard/content/[id]│ └── page.tsx├── analytics/ # Analytics dashboard│ └── page.tsx # /dashboard/analytics├── team/ # Team management│ └── page.tsx # /dashboard/team├── settings/ # Organization settings│ ├── page.tsx # /dashboard/settings│ ├── profile/ # Profile settings│ ├── billing/ # Billing settings│ ├── compliance/ # Compliance settings│ └── security/ # Security settings└── admin/ # Admin panel (admin only) └── page.tsx # /dashboard/adminOnboarding Flow (src/app/onboarding/)
Section titled “Onboarding Flow (src/app/onboarding/)”First-time setup for service providers:
src/app/onboarding/├── organization/ # Step 1: Create organization│ └── page.tsx # /onboarding/organization├── service-provider/ # Step 2: Service provider profile│ └── page.tsx # /onboarding/service-provider└── team/ # Step 3: Invite team members └── page.tsx # /onboarding/teamComponents Directory (src/components/)
Section titled “Components Directory (src/components/)”Base UI Components (src/components/ui/)
Section titled “Base UI Components (src/components/ui/)”46 reusable UI primitives built with Radix UI and shadcn/ui:
src/components/ui/├── button.tsx # Button component├── input.tsx # Text input├── select.tsx # Select dropdown├── dialog.tsx # Modal dialog├── table.tsx # Data table├── card.tsx # Card container├── form.tsx # Form wrapper (react-hook-form)├── badge.tsx # Badge/pill├── avatar.tsx # User avatar├── toast.tsx # Toast notifications (Sonner)├── tabs.tsx # Tab navigation├── accordion.tsx # Accordion/collapsible├── dropdown-menu.tsx # Dropdown menu├── alert.tsx # Alert messages├── skeleton.tsx # Loading skeleton└── ... (31 more components)Code Example:
import { cn } from "@/lib/utils"
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> { variant?: 'default' | 'outline' | 'ghost' size?: 'sm' | 'md' | 'lg'}
export function Button({ variant = 'default', size = 'md', className, ...props}: ButtonProps) { return ( <button className={cn( "inline-flex items-center justify-center rounded-md", { 'bg-primary text-primary-foreground': variant === 'default', 'border border-primary': variant === 'outline', 'h-8 px-3 text-sm': size === 'sm', 'h-10 px-4': size === 'md', }, className )} {...props} /> )}Dashboard Components (src/components/dashboard/)
Section titled “Dashboard Components (src/components/dashboard/)”29 feature-specific components for dashboard functionality:
src/components/dashboard/├── analytics-dashboard.tsx # Main analytics view├── metrics-card.tsx # KPI metrics card├── campaign-list.tsx # Campaign list table├── campaign-card.tsx # Campaign card├── campaign-form.tsx # Campaign creation form├── client-list.tsx # Client list table├── client-card.tsx # Client card├── client-form.tsx # Client creation form├── content-editor.tsx # TipTap content editor├── content-list.tsx # Content list├── security-clearance-badge.tsx # Security clearance indicator├── sector-badge.tsx # Government/Business badge├── approval-flow-status.tsx # Content approval status├── team-member-list.tsx # Team members table├── invite-form.tsx # Team invitation form└── ... (14 more components)Code Example:
'use client'
import { Card } from '@/components/ui/card'import { Badge } from '@/components/ui/badge'import { SecurityClearanceBadge } from './security-clearance-badge'import type { Client } from '@prisma/client'
interface ClientCardProps { client: Client onEdit?: (client: Client) => void}
export function ClientCard({ client, onEdit }: ClientCardProps) { return ( <Card className="p-6"> <div className="flex items-start justify-between"> <div> <h3 className="text-lg font-semibold">{client.name}</h3> <div className="mt-2 flex gap-2"> <Badge variant={client.sector === 'GOVERNMENT' ? 'destructive' : 'success'}> {client.sector} </Badge> <SecurityClearanceBadge clearance={client.securityClearance} /> </div> </div> {onEdit && ( <Button variant="ghost" size="sm" onClick={() => onEdit(client)}> Edit </Button> )} </div> </Card> )}Screenshot Placeholder:
Services Directory (src/lib/services/)
Section titled “Services Directory (src/lib/services/)”25 service modules containing business logic:
src/lib/services/├── analytics.service.ts # Analytics and reporting├── campaign.service.ts # Campaign management├── client.service.ts # Client operations├── compliance.service.ts # POPIA compliance├── content.service.ts # Content management├── team.service.ts # Team member management├── auth.service.ts # Authentication helpers├── audit.service.ts # Audit logging├── consent.service.ts # Consent management├── email.service.ts # Email sending (Resend)├── invitation.service.ts # Invitation system├── organization.service.ts # Organization management├── reports/ # Report generation│ ├── analytics-reports.ts│ ├── compliance-reports.ts│ └── campaign-reports.ts└── __tests__/ # Service tests ├── client.service.test.ts └── compliance.service.test.tsCode Example:
import { prisma } from '@/lib/db'import { auditLog } from './audit.service'import type { Client, ClientSector, SecurityClearance } from '@prisma/client'
export const clientService = { /** * Create a new client with POPIA audit logging */ async create(data: CreateClientInput, userId: string): Promise<Client> { const client = await prisma.client.create({ data: { name: data.name, sector: data.sector, securityClearance: data.securityClearance, organizationId: data.organizationId, contactInfo: data.contactInfo, }, })
// POPIA audit log await auditLog({ organizationId: data.organizationId, userId, action: 'CLIENT_CREATED', resource: 'Client', resourceId: client.id, details: { clientName: client.name, sector: client.sector }, })
return client },
/** * Get clients by sector with security clearance filtering */ async getBySector( organizationId: string, sector: ClientSector, userClearance: SecurityClearance ): Promise<Client[]> { return prisma.client.findMany({ where: { organizationId, sector, securityClearance: { lte: userClearance, // User can only see clients within their clearance }, }, orderBy: { createdAt: 'desc' }, }) },}Database (prisma/)
Section titled “Database (prisma/)”Prisma schema and migrations:
prisma/├── schema.prisma # Database schema (28 models)├── migrations/ # Database migration files│ ├── 20250922_init/│ ├── 20250923_clients/│ ├── 20251015_campaigns/│ └── ...└── seed.ts # Database seeding scriptCode Example:
// prisma/schema.prisma (excerpt)model Client { id String @id @default(cuid()) organizationId String name String sector ClientSector // GOVERNMENT or BUSINESS clientType ClientType securityClearance SecurityClearance // BASIC, ENHANCED, CONFIDENTIAL contactInfo Json?
organization Organization @relation(fields: [organizationId], references: [id]) campaigns Campaign[] projects Project[]
createdAt DateTime @default(now()) updatedAt DateTime @updatedAt
@@index([organizationId]) @@index([sector]) @@index([securityClearance])}
enum ClientSector { GOVERNMENT BUSINESS}
enum SecurityClearance { BASIC ENHANCED CONFIDENTIAL}Key Configuration Files
Section titled “Key Configuration Files”next.config.mjs
Section titled “next.config.mjs”Next.js configuration:
/** @type {import('next').NextConfig} */const nextConfig = { typescript: { ignoreBuildErrors: false, }, eslint: { ignoreDuringBuilds: false, }, experimental: { serverActions: { allowedOrigins: ['localhost:3000', 'thrivesend.isutech.co.za'], }, },}
export default nextConfigtailwind.config.ts
Section titled “tailwind.config.ts”Tailwind CSS with semantic colors:
import type { Config } from 'tailwindcss'
const config: Config = { content: ['./src/**/*.{ts,tsx}'], theme: { extend: { colors: { primary: 'hsl(var(--primary))', secondary: 'hsl(var(--secondary))', success: 'hsl(var(--success))', warning: 'hsl(var(--warning))', error: 'hsl(var(--error))', }, }, },}
export default configFile Naming Conventions
Section titled “File Naming Conventions”Component Files
Section titled “Component Files”- React Components: PascalCase with
.tsxextension- Example:
ClientCard.tsx,CampaignForm.tsx
- Example:
- Server Components: Default export, no ‘use client’ directive
- Client Components: Must include ‘use client’ directive
API Routes
Section titled “API Routes”- Route Handlers:
route.ts(Next.js convention) - Dynamic Routes:
[paramName]/route.ts - HTTP Methods: Named exports (GET, POST, PUT, DELETE)
Service Files
Section titled “Service Files”- Services:
kebab-case.service.ts- Example:
client.service.ts,analytics.service.ts
- Example:
Test Files
Section titled “Test Files”- Unit Tests:
*.test.tsor*.test.tsx - Integration Tests:
*.integration.test.ts - E2E Tests:
*.spec.ts(Playwright)
Import Aliases
Section titled “Import Aliases”TypeScript path aliases for cleaner imports:
// tsconfig.json{ "compilerOptions": { "paths": { "@/*": ["./src/*"], "@/components/*": ["./src/components/*"], "@/lib/*": ["./src/lib/*"], "@/app/*": ["./src/app/*"] } }}Usage:
// Instead of:import { Button } from '../../../components/ui/button'
// Use:import { Button } from '@/components/ui/button'Next Steps
Section titled “Next Steps”- Review System Design for architecture
- Explore Component Patterns for UI development
Last Updated: October 22, 2025