README.md
August 9, 2025 Β· View on GitHub
Note: This project uses shared development configurations (linting, formatting) defined in the repository root. Please see the root README.md for initial setup instructions and tooling details (ESLint, Prettier).
This is a Next.js project bootstrapped with create-next-app.
Getting Started π
This project uses Bun as the runtime and package manager. Make sure you have it installed!
First, ensure you have the necessary environment variables set up. Copy the example file:
cp .env.example .env.local
Then, edit .env.local and fill in the required values.
Required Environment Variables
The following variables are required for the dashboard to function:
Supabase Configuration:
NEXT_PUBLIC_SUPABASE_URL="https://your-project-id.supabase.co"
NEXT_PUBLIC_SUPABASE_ANON_KEY="your-supabase-anon-key"
SUPABASE_SERVICE_ROLE_KEY="your-supabase-service-role-key"
API Configuration:
NEXT_PUBLIC_API_URL="http://localhost:8000" # Backend API URL
NEXT_PUBLIC_APP_URL="http://localhost:3000" # Frontend URL
Optional Environment Variables
Stripe (for billing features):
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY="pk_test_your_stripe_publishable_key"
Analytics & Monitoring:
NEXT_PUBLIC_POSTHOG_KEY="your-posthog-key"
NEXT_PUBLIC_SENTRY_DSN="your-sentry-dsn"
Feature Flags:
NEXT_PUBLIC_ENVIRONMENT_TYPE="development"
NEXT_PUBLIC_PLAYGROUND="true"
See the .env.example file for the complete list of available configuration options.
Next, install the frontend dependencies:
bun install
Backend API Setup (Crucial!) β
The dashboard frontend relies exclusively on the backend API server (located in the api/ directory) for all data fetching and actions after user authentication.
You MUST run the backend API locally before starting the frontend development server to test features correctly.
Follow the setup instructions in the api/README.md to run the backend either natively (Python) or using Docker. Ensure the API is running and accessible at the URL specified in your NEXT_PUBLIC_API_URL environment variable (typically http://localhost:8000).
Billing & Subscription Features π³
The dashboard includes comprehensive billing and subscription management features powered by Stripe integration. This section covers the frontend billing components and their functionality.
Billing Architecture (Frontend)
The billing system in the dashboard follows this flow:
- User Authentication via Supabase provides JWT tokens
- Billing Pages (
/settings/organization) display organization subscription status - Stripe Elements handle secure payment processing
- Real-time Updates via polling and webhook-triggered data refetch
- Backend API manages all Stripe operations and subscription state
Key Billing Components
Billing Settings Page (app/(with-layout)/settings/organization/)
- Main Page (
page.tsx): Orchestrates billing operations and state management - OrganizationsList (
components/OrganizationsList.tsx): Displays subscription status and management options - EmbeddedCheckoutForm (
components/EmbeddedCheckoutForm.tsx): Stripe Elements integration for payments
Billing Features
Backend Integration
For complete billing setup including Stripe configuration, webhook handling, and API endpoints, see:
β‘οΈ ../api/README.md#billing--subscription-management
Environment Variables (Frontend)
# Required for billing features
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
NEXT_PUBLIC_API_URL=http://localhost:8000 # Backend API URL
Testing Billing Features
For local development:
- Backend Setup: Follow
../api/README.mdfor complete Stripe configuration (the docker version is best for billing see the -s option on just api-build/run) - Test Mode: Use Stripe test keys and test card numbers (e.g.,
4242424242424242) - Webhook Testing: Use
stripe listento forward webhooks to local backend - Frontend Testing: Access
/settings/organizationto test the complete flow
Billing Component Architecture
app/(with-layout)/settings/organization/
βββ page.tsx # Main billing page & state management
βββ components/
β βββ OrganizationsList.tsx # Subscription status & management UI
β βββ EmbeddedCheckoutForm.tsx # Stripe Elements payment form
βββ hooks/
βββ useStripeConfig.ts # Stripe configuration fetching
βββ useStripePricing.ts # Pricing information
Key Hooks & Utilities
useOrgs(): Fetches organization data including subscription statususeStripeConfig(): Retrieves Stripe publishable keys and configurationuseStripePricing(): Gets current pricing informationfetchAuthenticatedApi(): Makes authenticated requests to billing endpoints
Billing Error Handling
The frontend includes comprehensive error handling:
- Network Errors: Retry mechanisms and user-friendly messages
- Payment Failures: Clear error display and recovery options
- State Synchronization: Polling to ensure UI reflects actual subscription state
- Permission Errors: Appropriate messaging for non-admin users
Running the Frontend Dev Server
Once the backend API is running and frontend dependencies are installed (bun install), start the frontend development server:
bun run dev
Open http://localhost:3000 with your browser to see the magic happen β¨.
The page auto-updates as you edit files. Hot reloading is pretty sweet, eh?
This project uses next/font to automatically optimize and load Inter, a custom Google Font.
Development Workflow π οΈ
Working on the dashboard? Here are some helpful commands:
- Run Dev Server:
bun run dev(You already know this one!) - Build for Production:
bun run build(Checks for build errors) - Linting:
bun run lint(Keep the code style consistent, please! π) - Type Checking:
bunx tsc --noEmit- This command is your best friend for finding all TypeScript errors at once, unlike
bun run buildwhich might stop at the first error. - Important: Make sure you run this command from within the
dashboarddirectory so it can find thetsconfig.json.
- This command is your best friend for finding all TypeScript errors at once, unlike
Project Structure πΊοΈ
Navigating the codebase? Here's a quick lay of the land:
app/: The heart of the Next.js App Router. Contains layouts, pages, route handlers (APIs), and loading/error components.(with-layout)/: Routes in here share the main application layout (header, sidebar, etc.).- Other folders often correspond directly to URL paths.
components/: Reusable UI components used across the application. Organized by feature or UI pattern.ui/: Generally contains lower-level, shadcn-ui based components (Button, Card, etc.).
lib/: Utility functions, type definitions (types_db.ts), constants, and external service integrations (like Supabase client setup inlib/supabase/).hooks/: Custom React hooks, especially for data fetching (likeuseMetrics,useTraces). They often rely on the context providers.public/: Static assets served directly (images, fonts).tests/: Unit and integration tests (using Jest, potentially).styles/: Global styles (though most styling is done via Tailwind CSS within components).
(This is a brief overview, feel free to explore!)
Learn More
To learn more about Next.js, take a look at the following resources:
- Next.js Documentation - learn about Next.js features and API.
- Learn Next.js - an interactive Next.js tutorial.
You can check out the Next.js GitHub repository - your feedback and contributions are welcome!
Deploy on Vercel
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.
Frontend Data Fetching & Auth Architecture ποΈ (Revised)
This section outlines the revised architecture for handling authentication, API communication, and state management in the dashboard frontend.
Core Principles:
- Authentication via Supabase: User sign-up, sign-in, and session management are handled using the
@supabase/ssrlibrary on the client and server-side middleware. After successful authentication, a JWT is obtained from the Supabase session. - Backend API as Single Source of Truth: All data requests (user details, projects, orgs, traces, metrics, etc.) after login are directed exclusively to the backend API server (running at
NEXT_PUBLIC_API_URL). The frontend does not make direct calls to the Supabase database (except for specific auth actions like sign-in, sign-out, password reset, MFA management). - JWT for API Authorization: Every request to the backend API includes the Supabase JWT in the
Authorization: Bearer <token>header. - Centralized API Client: A dedicated function,
fetchAuthenticatedApi(inlib/api-client.ts), handles all communication with the backend API. It automatically retrieves the current JWT from the Supabase session (supabase.auth.getSession()) and attaches theAuthorizationheader. - React Query for Server State:
@tanstack/react-queryis used to manage server state, including data fetching (useQuery), caching, background updates, and mutations (useMutation). - Custom Hooks for Data Fetching: Data fetching logic is primarily encapsulated in custom hooks (located in
hooks/queries/, e.g.,useUser,useProjects,useOrgs, and directly inhooks/foruseTraces,useMetrics). These hooks utilizeuseQueryoruseMutationfrom React Query. - API Helper Functions: For many common operations (User, Org, Project CRUD), hooks call dedicated API helper functions (e.g.,
fetchUserAPI,createOrgAPI,updateProjectAPI) defined inlib/api/. These helper functions then usefetchAuthenticatedApiinternally to perform the actual request. - Direct API Client Usage in Hooks: For more complex queries like fetching traces (
useTraces) or metrics (useMetrics), the hooks often callfetchAuthenticatedApidirectly, constructing the necessary endpoint and query parameters based on context (e.g., selected project ID, date range, filters). - Shared Client State: Shared cross-component state, such as the currently selected project and date range, is managed using React Context via dedicated providers (e.g.,
ProjectProviderdefined withinapp/(with-layout)/projects-manager.tsx,DashboardStateProviderinapp/(with-layout)/dashboard-state-provider.tsx).
Simplified Flow (Example: Fetching User Data):
- User authenticates using Supabase UI/client functions.
- Frontend gets Supabase session and JWT.
- Component needs user profile data.
- Component calls relevant hook (e.g.,
useUser()). useUserhook callsuseQuerywith a query function that calls the API helper (fetchUserAPI).fetchUserAPIcallsfetchAuthenticatedApi('/opsboard/users/me')withmethod: 'GET'.fetchAuthenticatedApiretrieves the JWT fromsupabase.auth.getSession().fetchAuthenticatedApimakes thefetchcall tohttp://localhost:8000/opsboard/users/mewith theAuthorization: Bearer <token>header.- Backend API (
api/) validates the JWT usingDepends(get_current_user). - Backend fetches user data from the database.
- Backend returns data (JSON).
fetchAuthenticatedApiparses the JSON response.fetchUserAPIreturns the data to theuseQueryhook.- React Query manages the state, component re-renders with the fetched user data.
Key Changes from Previous Architecture:
- Removed direct Supabase database calls from frontend components (except for auth-specific actions).
- Removed the
OperationalTokenProviderand the concept of a separate operational token. - All authenticated data API calls use the Supabase JWT and go through
fetchAuthenticatedApi, either directly or via helper functions inlib/api/.
Cypress E2E Testing π§ͺ
For details on setting up and running End-to-End tests with Cypress, please refer to the dedicated README:
β‘οΈ cypress/README.md