MyUserJourney is a self-hosted, AI-powered analytics and CMS platform designed for comprehensive user behaviour tracking, SEO analysis, PPC campaign management, and content management. It provides a GA4-style navigation experience while being fully compliant with UK GDPR, UK PECR, EU GDPR, and EU ePrivacy Directives.
Live at: https://myuserjourney.co.uk
Businesses today face an impossible choice: use powerful analytics platforms that compromise user privacy and send data to third-party servers, or use privacy-focused alternatives that lack advanced features. Google Analytics 4 raises GDPR adequacy concerns with cross-border data transfers. Microsoft Clarity records sessions without granular consent. Amplitude and Mixpanel charge premium prices that exclude SMEs. None of them offer integrated AI insights, CMS, SEO auditing, and PPC management in a single self-hosted solution.
MyUserJourney eliminates this trade-off by combining enterprise-grade analytics with AI-powered intelligence and full privacy compliance in a single, self-hosted platform. It is the first open-source solution to unify real-time behavioural analytics, predictive AI (churn risk, revenue forecasting, conversion predictions), automated UX auditing, natural language analytics queries, SEO site auditing, PPC campaign management, and a complete CMS — all while maintaining GDPR/PECR compliance by design, not as an afterthought.
| Document | Description |
|---|---|
| Whitepaper | Technical architecture, innovation approach, competitive analysis |
| Impact Narrative | Global impact and real-world problem solving |
| Leadership Proof | Product leadership and innovation ownership |
| Global Relevance | Worldwide applicability and market potential |
| Innovation Statement | Competitive positioning and differentiation |
| Visual Evidence Guide | Screenshot and evidence collection checklist |
| Layer | Technology |
|---|---|
| Frontend | React 18, TypeScript, Vite, Tailwind CSS, Shadcn UI |
| State Management | TanStack React Query v5 |
| Charts | Recharts |
| Routing | Wouter |
| Backend | Node.js, Express.js, TypeScript |
| Database | PostgreSQL |
| ORM | Drizzle ORM |
| Authentication | Passport.js (Local + Google OAuth 2.0) |
| Nodemailer | |
| AI | OpenAI API (GPT-4o-mini, configurable provider) |
| Payments | Stripe (automated invoicing) |
| File Uploads | Multer |
myuserjourney/
├── client/ # Frontend React application
│ └── src/
│ ├── components/ # Reusable UI components
│ │ └── ui/ # Shadcn UI components
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Utility functions & API client
│ └── pages/ # Route page components
│ └── public/ # Public-facing pages
├── server/ # Backend Express application
│ ├── auth.ts # Authentication (Passport.js, OAuth, password reset)
│ ├── routes.ts # API route handlers
│ ├── storage.ts # Database access layer (CRUD operations)
│ ├── ai-service.ts # AI/LLM integration service
│ ├── db.ts # Database connection
│ ├── index.ts # Server entry point
│ ├── seed.ts # Database seed data
│ └── vite.ts # Vite dev server integration
├── shared/
│ └── schema.ts # Drizzle ORM schema (27 tables) + Zod validators
├── uploads/ # User-uploaded files (gitignored)
├── .env.example # Environment variable template
├── .gitignore # Git ignore rules
├── drizzle.config.ts # Drizzle ORM configuration
├── tailwind.config.ts # Tailwind CSS configuration
├── vite.config.ts # Vite build configuration
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
├── LICENSE # MIT License
├── README.md # This file
└── whitepaper.md # Technical whitepaper
git clone https://github.com/yourusername/myuserjourney.git
cd myuserjourney
npm install
cp .env.example .env
Edit .env with your actual values. See Environment Variables for details.
Ensure PostgreSQL is running, then push the schema:
npm run db:push
This creates all 27 tables defined in shared/schema.ts.
npm run dev
The application will be available at http://localhost:5000.
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
SESSION_SECRET |
Yes | Secret key for session encryption (use a strong random string) |
GOOGLE_CLIENT_ID |
No | Google OAuth 2.0 Client ID |
GOOGLE_CLIENT_SECRET |
No | Google OAuth 2.0 Client Secret |
OPENAI_API_KEY |
No | OpenAI API key for AI features |
OPENAI_API_BASE_URL |
No | OpenAI API base URL (default: https://api.openai.com/v1) |
STRIPE_SECRET_KEY |
No | Stripe secret key for payment processing |
STRIPE_PUBLISHABLE_KEY |
No | Stripe publishable key |
STRIPE_WEBHOOK_DOMAIN |
No | Domain for Stripe webhook endpoint (e.g., https://yourdomain.com) |
ADMIN_EMAIL |
No | Email address to auto-promote to admin on startup (recommended for first-time setup) |
ADMIN_DEFAULT_PASSWORD |
No | Password for seeded admin account (admin@analytics.io). Min 8 chars. Required only for initial setup. |
NODE_ENV |
No | development or production (default: development) |
PORT |
No | Server port (default: 5000) |
Generate a secure session secret:
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
CREATE DATABASE myuserjourney;
CREATE USER myuser WITH ENCRYPTED PASSWORD 'yourpassword';
GRANT ALL PRIVILEGES ON DATABASE myuserjourney TO myuser;
DATABASE_URL in your .env:DATABASE_URL=postgresql://myuser:yourpassword@localhost:5432/myuserjourney
npm run db:push
The platform uses 27 PostgreSQL tables managed by Drizzle ORM:
users - User accounts with role-based accesspassword_resets - Secure password reset tokensprojects - Analytics project configurationsevents - Tracked analytics eventsfunnels - Conversion funnel definitionsseo_analyses - SEO audit resultsppc_campaigns - PPC campaign datacustom_reports - User-defined reportsconsent_settings / consent_records - GDPR consent managementsite_settings / cms_pages / cms_files - CMS contentsmtp_settings - Email configurationcontact_submissions - Contact form entriesshared/schema.ts for the complete schema)https://yourdomain.comhttp://localhost:5000 (for development)https://yourdomain.com/api/auth/google/callbackhttp://localhost:5000/api/auth/google/callback (for development).env fileSMTP is configured through the Admin Panel at runtime (no environment variables required):
smtp.gmail.com)587 for TLS, 465 for SSL)SMTP is used for:
npm run dev
This starts both the Express backend and Vite frontend dev server on port 5000 with hot module replacement.
npm run check
npm run build
This compiles TypeScript and bundles the frontend with Vite.
npm start
The production server serves the built frontend as static files.
npm run buildNODE_ENV=production in your environmentserver {
listen 443 ssl;
server_name myuserjourney.co.uk;
ssl_certificate /etc/letsencrypt/live/myuserjourney.co.uk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myuserjourney.co.uk/privkey.pem;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
The application can be deployed to any platform that supports Node.js and PostgreSQL:
Access the admin panel at /admin (requires admin role).
| Tab | Description |
|---|---|
| Site Settings | Configure site name, tagline, brand colours, social media links |
| SMTP Configuration | Set up email server with test functionality |
| CMS Pages | Create, edit, publish/unpublish pages with SEO metadata |
| File Manager | Upload and manage files with drag-and-drop interface |
| User Management | View users, change roles, activate/deactivate accounts |
| Contact Submissions | Review contact form entries, update status, delete |
Option A: Auto-promote via ADMIN_EMAIL (recommended)
Set ADMIN_EMAIL in your .env file:
ADMIN_EMAIL=your@email.com
Register an account with that email address. On each app startup, the user matching ADMIN_EMAIL is automatically promoted to admin. This is the easiest method and requires no database access.
Option B: Seed admin account
Set ADMIN_DEFAULT_PASSWORD in your .env file before first run:
ADMIN_DEFAULT_PASSWORD=your-strong-password-here
On first startup, a default admin account is created:
admin@analytics.ioADMIN_DEFAULT_PASSWORDChange this password immediately after first login.
Option C: Promote via SQL
UPDATE users SET role = 'admin' WHERE email = 'your@email.com';
┌─────────────────────────────────────────────────────────┐
│ Client (Browser) │
│ React 18 + TypeScript + Tailwind CSS + Shadcn UI │
│ TanStack Query for state | Wouter for routing │
└──────────────────────┬──────────────────────────────────┘
│ HTTP/HTTPS
┌──────────────────────▼──────────────────────────────────┐
│ Express.js Server │
│ ┌──────────┐ ┌──────────┐ ┌────────────────────┐ │
│ │ Auth │ │ Routes │ │ AI Service │ │
│ │ Passport │ │ REST │ │ OpenAI API │ │
│ └──────────┘ └──────────┘ └────────────────────┘ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Storage Layer (CRUD) │ │
│ │ Type-safe Drizzle ORM queries │ │
│ └──────────────────────┬──────────────────────────┘ │
└─────────────────────────┼───────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────┐
│ PostgreSQL Database │
│ 27 tables, managed by Drizzle ORM │
└─────────────────────────────────────────────────────────┘
For a detailed technical deep-dive, see whitepaper.md.
All API endpoints return JSON. Authenticated endpoints require a valid session cookie (set automatically after login).
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/auth/register |
Register new account | No |
| POST | /api/auth/login |
Email/password login | No |
| GET | /api/auth/google |
Initiate Google OAuth | No |
| GET | /api/auth/google/callback |
Google OAuth callback | No |
| GET | /api/auth/me |
Get current user | Yes |
| POST | /api/auth/logout |
Log out | Yes |
| POST | /api/auth/forgot-password |
Request password reset | No |
| POST | /api/auth/reset-password |
Reset password with token | No |
Example: Register
curl -X POST http://localhost:5000/api/auth/register \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepass123", "firstName": "John", "lastName": "Doe"}'
Example: Login
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "securepass123"}'
Response:
{
"id": "uuid",
"email": "user@example.com",
"username": "user",
"role": "user",
"firstName": "John",
"lastName": "Doe"
}
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/events |
Collect tracking event | No (uses project ID) |
| GET | /api/projects/:id/stats |
Dashboard statistics | Yes |
| GET | /api/projects/:id/realtime |
Real-time analytics | Yes |
| GET | /api/projects/:id/acquisition |
Acquisition data | Yes |
| GET | /api/projects/:id/engagement |
Engagement metrics | Yes |
| GET | /api/projects/:id/visitors |
Visitor list | Yes |
| GET | /api/projects/:id/events |
Event stream | Yes |
Example: Collect Event
curl -X POST http://localhost:5000/api/events \
-H "Content-Type: application/json" \
-d '{
"projectId": "your-project-id",
"eventType": "pageview",
"page": "/pricing",
"referrer": "https://google.com",
"visitorId": "visitor-123",
"sessionId": "session-456"
}'
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/public/site-settings |
Site branding and settings |
| GET | /api/public/pages |
List published CMS pages |
| GET | /api/public/pages/:slug |
Get single page by slug |
| POST | /api/public/contact |
Submit contact form |
Example: Submit Contact Form
curl -X POST http://localhost:5000/api/public/contact \
-H "Content-Type: application/json" \
-d '{"name": "Jane Doe", "email": "jane@example.com", "message": "Hello!"}'
| Method | Endpoint | Description |
|---|---|---|
| GET/PUT | /api/admin/site-settings |
Manage site settings |
| GET/PUT | /api/admin/smtp |
Manage SMTP configuration |
| POST | /api/admin/smtp/test |
Send test email |
| GET/POST/PUT/DELETE | /api/admin/pages |
Manage CMS pages |
| GET/POST/DELETE | /api/admin/files |
Manage uploaded files |
| GET/PUT/DELETE | /api/admin/users |
Manage user accounts |
| GET/PUT/DELETE | /api/admin/contacts |
Manage contact submissions |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| GET | /api/projects |
List user’s projects | Yes |
| POST | /api/projects |
Create new project | Yes |
| GET | /api/projects/:id |
Get project details | Yes |
| PUT | /api/projects/:id |
Update project | Yes |
| DELETE | /api/projects/:id |
Delete project | Yes |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
| POST | /api/projects/:id/ai/chat |
AI analytics chat | Yes |
| POST | /api/projects/:id/ai/predict |
Predictive analytics | Yes |
| POST | /api/projects/:id/ai/ux-audit |
AI UX audit | Yes |
| POST | /api/projects/:id/ai/marketing |
AI marketing copilot | Yes |
SESSION_SECRET environment variable is required for production. A fallback value is used in development only. Always set a strong, unique value for production deployments.ADMIN_DEFAULT_PASSWORD to be set. If not set, no default admin is created. Always change the admin password after first login.NODE_ENV=production), cookies are set with the secure flag, requiring HTTPS. Always deploy behind an SSL-terminating reverse proxy.| Metric | Status |
|---|---|
| GitHub Stars | Tracking adoption and community interest |
| Live Deployment | Production at myuserjourney.co.uk with SSL |
| Users Onboarded | Active admin and user accounts in production |
| Beta Testing | Internal testing across analytics, CMS, AI, and compliance features |
| Database Architecture | 27 production tables with full relational integrity |
| API Endpoints | 50+ RESTful endpoints covering analytics, CMS, AI, privacy, and admin |
| GDPR Compliance | Full UK GDPR, UK PECR, EU GDPR, and EU ePrivacy Directive compliance |
| AI Features Shipped | Predictive analytics, UX auditor, marketing copilot, NLP insights |
| Performance | Sub-second API response times, real-time event processing, optimised PostgreSQL queries |
| Code Quality | End-to-end TypeScript, Zod validation, Drizzle ORM type safety, bcrypt authentication |
Supporting evidence for the platform’s capabilities is organised in the evidence/ directory:
evidence/
screenshots/ Platform UI screenshots (dashboard, AI, admin, privacy)
whitepaper/ Exported whitepaper and technical documents (PDF)
architecture/ System diagrams, schema visuals, data flow charts
demo-videos/ Screen recordings of platform functionality
Refer to the Visual Evidence Guide for a detailed checklist of what to capture and how to present each item.
| Phase | Timeline | Features |
|---|---|---|
| v1.1 | Q2 2026 | Heatmaps, scroll depth tracking, A/B testing framework |
| v1.2 | Q3 2026 | Multi-tenant SaaS mode, team collaboration, role-based dashboards |
| v1.3 | Q4 2026 | Real-time alerting engine, anomaly detection, webhook integrations |
| v2.0 | Q1 2027 | Mobile SDK (iOS/Android), server-side tracking, data warehouse connectors |
| v2.1 | Q2 2027 | White-label reseller programme, API marketplace, plugin architecture |
git checkout -b feature/your-featuregit commit -m 'Add your feature'git push origin feature/your-featurePlease ensure your code follows the existing style conventions and includes appropriate TypeScript types.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with purpose by the MyUserJourney team.