Getting Started

Project Structure

Understanding the Straktur codebase organization

Project Structure

TL;DR: Feature-first architecture. All code for a feature lives in /src/features/<name>/.

Overview

src/
├── proxy.ts                  # Route-level auth & redirects
├── app/                      # Next.js App Router (pages)
├── features/                 # Feature modules (business logic)
├── server/                   # oRPC routers (API layer)
├── components/               # Shared UI components
├── hooks/                    # Custom React hooks
├── lib/                      # Utilities and configuration
├── emails/                   # Email templates (React Email)
└── scripts/                  # Seed & migration scripts

Directory Details

/src/app/ - Pages & Routes

Next.js App Router structure:

app/
├── (auth)/                   # Auth pages (login, register)
│   ├── login/
│   ├── register/
│   ├── forgot-password/
│   └── reset-password/

├── (dashboard)/              # Main app (requires auth)
│   ├── examples/             # Reference implementations (DO NOT modify)
│   │   ├── dashboard/
│   │   ├── clients/
│   │   │   ├── page.tsx      # List page
│   │   │   ├── new/page.tsx  # Create page
│   │   │   └── [id]/page.tsx # Detail page
│   │   ├── contacts/
│   │   ├── activities/
│   │   └── files/
│   ├── users/
│   └── settings/
│       ├── profile/
│       ├── organizations/
│       └── dictionaries/

├── org/select/               # Organization selector
├── invite/[token]/           # Invitation acceptance
├── pending-approval/         # Approval pending page

├── api/
│   ├── auth/[...all]/        # better-auth handler
│   ├── rpc/[[...rest]]/      # oRPC endpoint (single API entry)
│   ├── health/               # Health check
│   ├── storage/              # File upload/download
│   ├── images/               # Image serving
│   └── avatar/               # Avatar endpoints

└── layout.tsx

Key patterns:

  • (auth) and (dashboard) are route groups (no URL impact)
  • [id] is a dynamic segment
  • [[...rest]] is a catch-all route
  • examples/ contains golden path reference code — build your features alongside it

/src/features/ - Business Logic

Each feature is self-contained:

features/
├── examples/                 # Reference implementations (DO NOT modify)
│   ├── clients/
│   │   ├── index.ts          # Client-safe exports (types, hooks, UI)
│   │   ├── server.ts         # Server-only exports (queries, actions)
│   │   ├── queries.ts        # Database read operations
│   │   ├── actions.ts        # Database write operations
│   │   ├── validation.ts     # Zod schemas
│   │   ├── types.ts          # Domain types (optional)
│   │   └── ui/               # Feature-specific components
│   ├── contacts/
│   ├── activities/
│   └── files/

├── auth/                     # Login, signup, password reset
├── organizations/            # Organization CRUD
├── dictionaries/             # Lookup values
├── invitations/              # User invitations
└── users/                    # User management

Import rules:

// ✅ Client Components - import from index.ts
import { ClientCard, useClients } from "@/features/examples/clients"

// ✅ Server/Routers - import from server.ts
import { listClients, createClient } from "@/features/examples/clients/server"

// ❌ NEVER import server.ts from Client Components

/src/server/ - API Layer (oRPC)

server/
├── orpc.ts                   # Procedure definitions (authedProcedure, etc.)
├── context.ts                # Server context (organizationId, userId, session)
├── search-config.ts          # Global search query config (server-only)
└── routers/
    ├── index.ts              # AppRouter - aggregates all routers
    ├── examples/             # Reference routers (DO NOT modify)
    │   ├── index.ts
    │   ├── clients.ts
    │   ├── contacts.ts
    │   ├── activities.ts
    │   ├── dashboard.ts
    │   └── files.ts
    ├── users.ts
    ├── dictionaries.ts
    ├── invitations.ts
    └── search.ts             # Global search endpoint

All routers are combined in index.ts and exposed via single /api/rpc endpoint.

/src/components/ - Shared UI

components/
├── ui/                       # shadcn/ui primitives
│   ├── button.tsx
│   ├── input.tsx
│   ├── dialog.tsx
│   └── ...

├── data-table/               # Table system
│   ├── data-table.tsx
│   ├── data-table-toolbar.tsx
│   ├── data-table-pagination.tsx
│   ├── bulk-actions.tsx
│   ├── data-table-export.tsx
│   └── ...

├── detail-page/              # Detail page layout
│   ├── detail-page-wrapper.tsx
│   ├── section-card.tsx
│   ├── property-row.tsx
│   └── page-tabs.tsx

├── detail-sheet/             # Side panel forms
│   ├── detail-sheet.tsx
│   ├── detail-sheet-form.tsx
│   └── sheet-header.tsx

├── inline-edit/              # Inline editing
│   ├── editable-text.tsx
│   ├── editable-select.tsx
│   ├── editable-number.tsx
│   └── editable-url.tsx

├── dashboard/                # Dashboard widgets
│   ├── stat-card.tsx
│   ├── activity-feed.tsx
│   └── area-chart-card.tsx

├── command-palette/          # Global search / command palette
├── providers/                # Context providers (query, theme, organization)

└── layout/                   # App shell
    ├── app-sidebar.tsx
    ├── header.tsx
    └── entity-header.tsx

/src/hooks/ - Custom Hooks

hooks/
├── use-format-currency.ts    # Currency formatting (reads org context)
├── use-data-table-url-state.ts
├── use-confirm-dialog.ts
├── use-autosave.ts
├── use-debounced-value.ts
├── use-dirty-form.ts
├── use-embedded-table.ts
├── use-optimistic-update.ts
└── ...

/src/lib/ - Utilities

lib/
├── orpc/
│   └── client.ts             # orpcUtils - TanStack Query integration

├── auth/
│   ├── index.ts              # Main auth exports
│   ├── roles.ts              # RBAC (owner, admin, member, viewer)
│   ├── session.ts            # Session helpers
│   └── providers/            # Auth provider implementations

├── db/
│   ├── index.ts              # Drizzle client
│   └── schema/               # Database tables
│       ├── auth.ts
│       ├── dictionaries.ts
│       ├── example-clients.ts
│       ├── example-contacts.ts
│       ├── example-activities.ts
│       ├── example-files.ts
│       └── ...

├── config/
│   ├── index.ts              # appConfig (central configuration)
│   ├── navigation.ts         # Nav items
│   ├── searchable-entities.ts # Global search config (client-safe)
│   ├── examples.ts           # Examples mode utilities
│   ├── currencies.ts         # Currency configuration
│   └── colors.ts             # Theme colors

├── storage/                  # File storage adapters (S3, Supabase)
├── email/                    # Email provider factory (Resend, SMTP, console)
├── api-errors/               # Client error handling & validation
├── url-state/                # URL state management
├── utils/
│   └── format.ts             # Formatting (date, currency, number)

└── env.ts                    # Environment variables (T3 Env)

/src/emails/ - Email Templates

emails/
├── welcome-email.tsx
├── invite-email.tsx
├── password-reset.tsx
└── components/               # Shared email components
    ├── email-layout.tsx
    ├── email-header.tsx
    └── email-footer.tsx

File Reference

Need to...Look in...
Add a pagesrc/app/(dashboard)/
Add business logicsrc/features/<name>/
Add an API endpointsrc/server/routers/
Add a shared componentsrc/components/
Change database schemasrc/lib/db/schema/
Configure the appsrc/lib/config/
Change auth behaviorsrc/lib/auth/
Add an email templatesrc/emails/
Add a custom hooksrc/hooks/

Reference Implementation

The examples directory contains golden path implementations. Study the Clients feature to understand all patterns:

WhatWhere
Feature modulesrc/features/examples/clients/
oRPC routersrc/server/routers/examples/clients.ts
List pagesrc/app/(dashboard)/examples/clients/page.tsx
Detail pagesrc/app/(dashboard)/examples/clients/[id]/page.tsx
Create pagesrc/app/(dashboard)/examples/clients/new/page.tsx

Do not modify the examples directory. Create your own features alongside it, following the same patterns.


On this page