mirror of
https://github.com/umami-software/umami.git
synced 2026-05-30 06:47:25 +00:00
Complete merge.
This commit is contained in:
@@ -1,97 +0,0 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file provides guidance for AI coding agents working in this repository.
|
||||
|
||||
## Project overview
|
||||
|
||||
Umami is a privacy-focused web analytics platform built with Next.js 15, React 19, and TypeScript.
|
||||
|
||||
- Primary database: PostgreSQL
|
||||
- Optional analytics backend: ClickHouse
|
||||
- Optional cache/session backend: Redis
|
||||
|
||||
## Development rules
|
||||
|
||||
- Assume a dev server is already running on port `3001`.
|
||||
- Do **not** start another dev server.
|
||||
- Use `pnpm` (not `npm` or `yarn`).
|
||||
- Avoid destructive shell commands unless explicitly requested.
|
||||
- Ask before running `git commit` or `git push`.
|
||||
|
||||
## Common commands
|
||||
|
||||
```bash
|
||||
# Development
|
||||
pnpm dev
|
||||
pnpm build
|
||||
pnpm start
|
||||
|
||||
# Database
|
||||
pnpm build-db
|
||||
pnpm update-db
|
||||
pnpm check-db
|
||||
pnpm seed-data
|
||||
|
||||
# Code quality
|
||||
pnpm lint
|
||||
pnpm format
|
||||
pnpm check
|
||||
pnpm test
|
||||
|
||||
# Build specific parts
|
||||
pnpm build-tracker
|
||||
pnpm build-geo
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
- `src/app/`: Next.js App Router routes and API endpoints
|
||||
- `src/components/`: UI components and hooks
|
||||
- `src/lib/`: shared utilities and infrastructure helpers
|
||||
- `src/queries/`: data access layer (Prisma + raw SQL)
|
||||
- `src/store/`: Zustand stores
|
||||
- `src/tracker/`: standalone client tracking script
|
||||
- `prisma/`: schema and migrations
|
||||
|
||||
## Key implementation patterns
|
||||
|
||||
### API request validation
|
||||
|
||||
Use Zod + `parseRequest` in API handlers:
|
||||
|
||||
```ts
|
||||
const schema = z.object({ /* fields */ });
|
||||
const { body, error } = await parseRequest(request, schema);
|
||||
if (error) return error();
|
||||
```
|
||||
|
||||
### Authentication
|
||||
|
||||
- JWT via `Authorization: Bearer <token>`
|
||||
- Share token via `x-umami-share-token`
|
||||
- Role model: `admin`, `manager`, `user`
|
||||
|
||||
### Client data fetching
|
||||
|
||||
- React Query defaults: `staleTime` 60s, no retry, no refetch on window focus
|
||||
|
||||
### Styling
|
||||
|
||||
- CSS Modules with CSS variables and theme support
|
||||
|
||||
## Environment variables
|
||||
|
||||
Common env vars:
|
||||
|
||||
- `DATABASE_URL`
|
||||
- `APP_SECRET`
|
||||
- `CLICKHOUSE_URL`
|
||||
- `REDIS_URL`
|
||||
- `BASE_PATH`
|
||||
- `DEBUG`
|
||||
|
||||
## Runtime requirements
|
||||
|
||||
- Node.js 18.18+
|
||||
- PostgreSQL 12.14+
|
||||
- `pnpm`
|
||||
@@ -1,100 +0,0 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Umami is a privacy-focused web analytics platform built with Next.js 15, React 19, and TypeScript. It serves as an alternative to Google Analytics, storing data in PostgreSQL (primary) with optional ClickHouse for time-series analytics.
|
||||
|
||||
## Development
|
||||
|
||||
Assume a dev server is always running on port 3001. Do not start the dev server.
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Development
|
||||
npm run dev # Start dev server on port 3001 with Turbopack
|
||||
npm run build # Full production build (includes db setup, tracker, geo data)
|
||||
npm run start # Start production server
|
||||
|
||||
# Database
|
||||
npm run build-db # Generate Prisma client
|
||||
npm run update-db # Run Prisma migrations
|
||||
npm run check-db # Verify database connection
|
||||
npm run seed-data # Seed test data
|
||||
|
||||
# Code Quality
|
||||
npm run lint # Lint with Biome
|
||||
npm run format # Format with Biome
|
||||
npm run check # Format and lint with Biome
|
||||
npm run test # Run Jest tests
|
||||
|
||||
# Building specific parts
|
||||
npm run build-tracker # Build client-side tracking script (Rollup)
|
||||
npm run build-geo # Build geolocation database
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
### Directory Structure
|
||||
- `src/app/` - Next.js App Router (routes and API endpoints)
|
||||
- `(main)/` - Authenticated app routes (dashboard, websites, teams, boards, etc.)
|
||||
- `(collect)/` - Data collection routes
|
||||
- `api/` - REST API endpoints
|
||||
- `src/components/` - React components (charts, forms, common UI, hooks)
|
||||
- `src/lib/` - Core utilities (auth, crypto, date, prisma helpers, redis)
|
||||
- `src/queries/` - Data access layer (Prisma queries and raw SQL)
|
||||
- `src/store/` - Zustand state stores (app, dashboard, websites, cache)
|
||||
- `src/tracker/` - Client-side tracking script (lightweight IIFE)
|
||||
- `prisma/` - Database schema and migrations
|
||||
|
||||
### Key Patterns
|
||||
|
||||
**API Request Handling** - All API endpoints use Zod validation with `parseRequest`:
|
||||
```typescript
|
||||
const schema = z.object({ /* fields */ });
|
||||
const { body, error } = await parseRequest(request, schema);
|
||||
if (error) return error();
|
||||
```
|
||||
|
||||
**Authentication** - JWT tokens via Bearer header, share tokens via `x-umami-share-token` header for public dashboards. Role-based access: admin, manager, user.
|
||||
|
||||
**Data Fetching** - React Query with 60s stale time, no retry, no refetch on window focus.
|
||||
|
||||
**State Management** - Zustand for client state, localStorage for user preferences.
|
||||
|
||||
**Styling** - CSS Modules with CSS variables for theming (light/dark mode).
|
||||
|
||||
### Database
|
||||
|
||||
- **ORM**: Prisma 7.x with PostgreSQL adapter
|
||||
- **Schema**: `prisma/schema.prisma` - 14 models (User, Team, Website, Session, WebsiteEvent, EventData, etc.)
|
||||
- **Query helpers**: `src/lib/prisma.ts` has dynamic SQL generation functions (`getDateSQL`, `mapFilter`, `getSearchSQL`)
|
||||
- **Raw SQL**: Complex analytics queries use `{{param}}` template placeholders for safe binding
|
||||
|
||||
### Tracker Script
|
||||
|
||||
The tracking script in `src/tracker/index.js` is a standalone IIFE (~3-4KB) built with Rollup. It sends events to `/api/send`. Alternative script names can be configured via `TRACKER_SCRIPT_NAME` env var.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Key variables in `.env`:
|
||||
```
|
||||
DATABASE_URL # PostgreSQL connection string (required)
|
||||
APP_SECRET # Encryption/signing secret
|
||||
CLICKHOUSE_URL # Optional ClickHouse for analytics
|
||||
REDIS_URL # Optional Redis for caching/sessions
|
||||
BASE_PATH # App base path (e.g., /analytics)
|
||||
DEBUG # Debug namespaces (e.g., umami:*)
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js 18.18+
|
||||
- PostgreSQL 12.14+
|
||||
- pnpm (package manager)
|
||||
|
||||
## Git Workflow
|
||||
|
||||
Always ask for confirmation before running `git commit` or `git push`.
|
||||
@@ -4,7 +4,16 @@ import { useBoard } from '@/components/hooks';
|
||||
|
||||
export function BoardControls() {
|
||||
const { board } = useBoard();
|
||||
const websiteId = board?.parameters?.websiteId;
|
||||
const boardWebsiteId = board?.parameters?.websiteId;
|
||||
const componentWebsiteIds = board?.parameters?.rows
|
||||
?.flatMap(row => row.columns)
|
||||
.map(column => column.component?.websiteId)
|
||||
.filter(Boolean);
|
||||
const fallbackWebsiteId =
|
||||
componentWebsiteIds && new Set(componentWebsiteIds).size === 1
|
||||
? componentWebsiteIds[0]
|
||||
: undefined;
|
||||
const websiteId = boardWebsiteId || fallbackWebsiteId;
|
||||
|
||||
if (!websiteId) {
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user