mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 23:39:40 +02:00
## New Features ### Network Graph Visualization (Contacts, Calendar, Todo) - D3.js force simulation for physics-based layout - Zoom & pan with mouse/touchpad - Keyboard shortcuts: +/- zoom, 0 reset, Esc deselect, / search, F focus - Filtering by tags, company/location/project, connection strength - Shared components in @manacore/shared-ui ### Central Tags API (mana-core-auth) - CRUD endpoints for tags - Schema: tags table with userId, name, color, app - Shared tag components in @manacore/shared-ui ### Custom Themes System - Theme editor with live preview and color picker - Community theme gallery - Theme sharing (public, unlisted, private) - Backend API in mana-core-auth ### Todo App Extensions - Glass-pill design for task input and items - Settings page with 20+ preferences - Task edit modal with inline editing - Statistics page with visualizations - PWA support with offline capabilities - Multiple kanban boards ### Contacts App Features - Duplicate detection - Photo upload - Batch operations - Enhanced favorites page with multiple view modes - Alphabet view improvements - Search modal ### Help System - @manacore/shared-help-content - @manacore/shared-help-ui - @manacore/shared-help-types ### Other Features - Themes page for all apps - Referral system frontend - CommandBar (global search) - Skeleton loaders - Settings page improvements ## Bug Fixes - Network graph simulation initialization - Database schema TEXT for user_id columns (Better Auth compatibility) - Various styling fixes ## Documentation - Daily report for 2025-12-10 - CI/CD deployment guide 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
482 lines
No EOL
11 KiB
Markdown
482 lines
No EOL
11 KiB
Markdown
# Complete PocketBase Development Setup Guide
|
|
|
|
## 📋 Overview
|
|
|
|
This guide documents the complete setup for local PocketBase development environment, separating it from production database to ensure safe development.
|
|
|
|
## 🎯 Current Status
|
|
|
|
### ✅ What's Already Done
|
|
|
|
1. **PocketBase is running** locally on `http://localhost:8090`
|
|
- Binary located at: `backend/pocketbase`
|
|
- Admin UI: http://localhost:8090/_/
|
|
- Process running on port 8090
|
|
|
|
2. **Admin Account Created**
|
|
```
|
|
Email: till.schneider@memoro.ai
|
|
Password: p0ck3t-RAJ
|
|
```
|
|
|
|
3. **Environment Variables Configured**
|
|
- `.env.development` - Points to `http://localhost:8090`
|
|
- `.env.production` - Points to `https://pb.ulo.ad`
|
|
- Automatic environment detection implemented
|
|
|
|
4. **Code Changes Completed**
|
|
All hardcoded production URLs have been removed and replaced with dynamic environment-based URLs:
|
|
- `src/lib/pocketbase.ts` - Dynamic URL selection
|
|
- `src/routes/p/[username]/+page.server.ts` - Environment-aware
|
|
- `src/lib/scripts/update-links-collection.js` - Flexible URL
|
|
- `src/routes/api/verify/+server.ts` - Dynamic redirect
|
|
- `src/hooks.server.ts` - CSP headers for both environments
|
|
|
|
5. **Scripts Created**
|
|
- `scripts/seed-local-db.js` - Creates test data
|
|
- `scripts/create-collections.mjs` - API-based collection creation (optional)
|
|
|
|
## 🔴 What Still Needs to Be Done
|
|
|
|
### Collections Need to Be Created
|
|
|
|
The database schema needs to be set up. The original `backend/pb_schema.json` is in an outdated format and cannot be imported into PocketBase v0.26.2.
|
|
|
|
## 📦 Collections Schema
|
|
|
|
### 1. Links Collection
|
|
|
|
**Type:** Base Collection
|
|
**Name:** `links`
|
|
|
|
**Fields:**
|
|
```javascript
|
|
{
|
|
short_code: {
|
|
type: 'text',
|
|
required: true,
|
|
unique: true,
|
|
min: 3,
|
|
max: 50,
|
|
pattern: '^[a-zA-Z0-9_/-]+$'
|
|
},
|
|
custom_code: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
original_url: {
|
|
type: 'url',
|
|
required: true
|
|
},
|
|
title: {
|
|
type: 'text',
|
|
required: false,
|
|
max: 200
|
|
},
|
|
description: {
|
|
type: 'text',
|
|
required: false,
|
|
max: 500
|
|
},
|
|
user_id: {
|
|
type: 'relation',
|
|
required: false,
|
|
collection: 'users',
|
|
cascadeDelete: true,
|
|
maxSelect: 1
|
|
},
|
|
is_active: {
|
|
type: 'bool',
|
|
required: false,
|
|
default: true
|
|
},
|
|
password: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
max_clicks: {
|
|
type: 'number',
|
|
required: false,
|
|
min: 0
|
|
},
|
|
expires_at: {
|
|
type: 'date',
|
|
required: false
|
|
},
|
|
click_count: {
|
|
type: 'number',
|
|
required: false,
|
|
default: 0
|
|
},
|
|
qr_code: {
|
|
type: 'file',
|
|
required: false,
|
|
maxSelect: 1,
|
|
maxSize: 5242880
|
|
},
|
|
tags: {
|
|
type: 'json',
|
|
required: false
|
|
},
|
|
utm_source: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
utm_medium: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
utm_campaign: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
account_owner: {
|
|
type: 'relation',
|
|
required: false,
|
|
collection: 'accounts',
|
|
maxSelect: 1
|
|
}
|
|
}
|
|
```
|
|
|
|
**API Rules:**
|
|
- List/View: `` (empty = public)
|
|
- Create: `@request.auth.id != ""`
|
|
- Update: `@request.auth.id = user_id`
|
|
- Delete: `@request.auth.id = user_id`
|
|
|
|
**Indexes:**
|
|
- `CREATE UNIQUE INDEX idx_short_code ON links (short_code)`
|
|
|
|
### 2. Clicks Collection
|
|
|
|
**Type:** Base Collection
|
|
**Name:** `clicks`
|
|
|
|
**Fields:**
|
|
```javascript
|
|
{
|
|
link_id: {
|
|
type: 'relation',
|
|
required: true,
|
|
collection: 'links',
|
|
cascadeDelete: true,
|
|
maxSelect: 1
|
|
},
|
|
ip_hash: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
user_agent: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
referer: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
browser: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
device_type: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
os: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
country: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
city: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
clicked_at: {
|
|
type: 'date',
|
|
required: false
|
|
},
|
|
utm_source: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
utm_medium: {
|
|
type: 'text',
|
|
required: false
|
|
},
|
|
utm_campaign: {
|
|
type: 'text',
|
|
required: false
|
|
}
|
|
}
|
|
```
|
|
|
|
**API Rules:**
|
|
- List/View: `` (empty = public for link tracking)
|
|
- Create: `` (empty = public for link tracking)
|
|
- Update: `null` (no updates allowed)
|
|
- Delete: `@request.auth.id = link_id.user_id`
|
|
|
|
### 3. Accounts Collection
|
|
|
|
**Type:** Base Collection
|
|
**Name:** `accounts`
|
|
|
|
**Fields:**
|
|
```javascript
|
|
{
|
|
name: {
|
|
type: 'text',
|
|
required: true
|
|
},
|
|
owner: {
|
|
type: 'relation',
|
|
required: true,
|
|
collection: 'users',
|
|
cascadeDelete: true,
|
|
maxSelect: 1
|
|
},
|
|
members: {
|
|
type: 'relation',
|
|
required: false,
|
|
collection: 'users',
|
|
cascadeDelete: false,
|
|
multiple: true
|
|
},
|
|
isActive: {
|
|
type: 'bool',
|
|
required: false,
|
|
default: true
|
|
},
|
|
planType: {
|
|
type: 'select',
|
|
required: false,
|
|
values: ['free', 'team', 'enterprise']
|
|
},
|
|
settings: {
|
|
type: 'json',
|
|
required: false
|
|
}
|
|
}
|
|
```
|
|
|
|
**API Rules:**
|
|
- List/View: `@request.auth.id = owner || @request.auth.id ?~ members`
|
|
- Create: `@request.auth.id != ""`
|
|
- Update: `@request.auth.id = owner`
|
|
- Delete: `@request.auth.id = owner`
|
|
|
|
### 4. Users Collection (Update Existing)
|
|
|
|
The users collection already exists (PocketBase auth collection). Add these custom fields:
|
|
|
|
**Additional Fields:**
|
|
```javascript
|
|
{
|
|
bio: { type: 'text', required: false },
|
|
website: { type: 'url', required: false },
|
|
location: { type: 'text', required: false },
|
|
github: { type: 'text', required: false },
|
|
twitter: { type: 'text', required: false },
|
|
linkedin: { type: 'text', required: false },
|
|
instagram: { type: 'text', required: false },
|
|
publicProfile: { type: 'bool', required: false, default: false },
|
|
showClickStats: { type: 'bool', required: false, default: true },
|
|
isPremium: { type: 'bool', required: false, default: false },
|
|
stripeCustomerId: { type: 'text', required: false },
|
|
stripeSubscriptionId: { type: 'text', required: false },
|
|
subscriptionStatus: { type: 'text', required: false },
|
|
planType: {
|
|
type: 'select',
|
|
required: false,
|
|
values: ['free', 'monthly', 'yearly', 'lifetime']
|
|
}
|
|
}
|
|
```
|
|
|
|
## 🚀 Setup Instructions for MCP Session
|
|
|
|
### Step 1: Verify PocketBase is Running
|
|
|
|
```bash
|
|
# Check if PocketBase is running
|
|
curl http://localhost:8090/api/health
|
|
|
|
# If not running, start it:
|
|
cd backend && ./pocketbase serve
|
|
```
|
|
|
|
### Step 2: Create Collections via MCP
|
|
|
|
When you connect the PocketBase MCP, use these commands:
|
|
|
|
1. **Authenticate as Admin:**
|
|
```
|
|
Email: till.schneider@memoro.ai
|
|
Password: p0ck3t-RAJ
|
|
```
|
|
|
|
2. **Create Links Collection:**
|
|
Use `mcp__pocketbase-server__create_collection` with the schema above
|
|
|
|
3. **Create Clicks Collection:**
|
|
Use `mcp__pocketbase-server__create_collection` with the schema above
|
|
|
|
4. **Create Accounts Collection:**
|
|
Use `mcp__pocketbase-server__create_collection` with the schema above
|
|
|
|
5. **Update Users Collection:**
|
|
Use `mcp__pocketbase-server__update_collection` to add custom fields
|
|
|
|
### Step 3: Load Test Data
|
|
|
|
After collections are created, run:
|
|
|
|
```bash
|
|
cd /Users/tillschneider/Documents/__00__Code/uload
|
|
node scripts/seed-local-db.js
|
|
```
|
|
|
|
This will create:
|
|
- 2 test users (test@localhost, demo@localhost)
|
|
- 4 test links (normal, protected, expired, limited)
|
|
- Sample click data
|
|
|
|
### Step 4: Start Application
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
The app will automatically use `http://localhost:8090` in development mode.
|
|
|
|
## 🧪 Test Data
|
|
|
|
### Test Users
|
|
```
|
|
Email: test@localhost
|
|
Password: test123456
|
|
|
|
Email: demo@localhost
|
|
Password: demo123456
|
|
```
|
|
|
|
### Test Links
|
|
- `http://localhost:5173/test1` - Normal link → https://example.com
|
|
- `http://localhost:5173/test2` - Link with 100 click limit → https://google.com
|
|
- `http://localhost:5173/protected` - Password protected (password: `secret123`) → https://github.com
|
|
- `http://localhost:5173/expired` - Expired link → https://stackoverflow.com
|
|
|
|
## 🔍 Verification Checklist
|
|
|
|
- [ ] PocketBase running on http://localhost:8090
|
|
- [ ] Admin can login at http://localhost:8090/_/
|
|
- [ ] All 3 collections created (links, clicks, accounts)
|
|
- [ ] Users collection updated with custom fields
|
|
- [ ] Test data loaded successfully
|
|
- [ ] App connects to local PocketBase (check console for "🔧 PocketBase URL: http://localhost:8090")
|
|
- [ ] Can create new links
|
|
- [ ] Link redirects work
|
|
- [ ] Click tracking works
|
|
- [ ] Password protection works
|
|
- [ ] User registration works
|
|
|
|
## 📝 Important Files
|
|
|
|
### Configuration Files
|
|
- `.env.development` - Local environment variables
|
|
- `.env.production` - Production environment variables
|
|
- `backend/pb_data/` - Local database files
|
|
- `backend/pb_migrations/` - Database migrations
|
|
|
|
### Scripts
|
|
- `scripts/seed-local-db.js` - Creates test data
|
|
- `scripts/create-collections.mjs` - API-based collection creation
|
|
|
|
### Modified Source Files
|
|
- `src/lib/pocketbase.ts` - Dynamic URL selection
|
|
- `src/routes/p/[username]/+page.server.ts` - Environment-aware routing
|
|
- `src/hooks.server.ts` - Dynamic CSP headers
|
|
- `src/routes/api/verify/+server.ts` - Dynamic verification URLs
|
|
|
|
## 🛠 Troubleshooting
|
|
|
|
### PocketBase Won't Start
|
|
```bash
|
|
# Kill existing process
|
|
pkill -f "pocketbase serve"
|
|
|
|
# Start fresh
|
|
cd backend && ./pocketbase serve
|
|
```
|
|
|
|
### Collections Not Found
|
|
- Ensure all collections are created with exact names (case-sensitive)
|
|
- Check API rules are set correctly
|
|
- Verify relations point to correct collections
|
|
|
|
### Environment Variables Not Loading
|
|
```bash
|
|
# Check current environment
|
|
echo $NODE_ENV
|
|
|
|
# Force development mode
|
|
NODE_ENV=development npm run dev
|
|
```
|
|
|
|
### Authentication Issues
|
|
- Admin email: `till.schneider@memoro.ai`
|
|
- Admin password: `p0ck3t-RAJ`
|
|
- If locked out, create new admin: `./pocketbase superuser create`
|
|
|
|
## 🔒 Security Notes
|
|
|
|
1. **Local Development Only** - Never use these credentials in production
|
|
2. **Git Ignored** - `backend/pb_data/` is gitignored (database files)
|
|
3. **No Production Data** - Never copy production data to local
|
|
4. **Separate Accounts** - Use different accounts for dev and prod
|
|
|
|
## 🎯 Next Steps After Collections Created
|
|
|
|
1. Run seed script for test data
|
|
2. Test all features locally
|
|
3. Make changes without fear of breaking production
|
|
4. Deploy when ready (automatic env detection)
|
|
|
|
## 📊 Environment Comparison
|
|
|
|
| Feature | Development | Production |
|
|
|---------|------------|------------|
|
|
| PocketBase URL | http://localhost:8090 | https://pb.ulo.ad |
|
|
| Database | Local SQLite | Cloud (Coolify) |
|
|
| Redis | localhost:6379 | Coolify Redis |
|
|
| Stripe | Test keys | Live keys |
|
|
| SSL | No (HTTP) | Yes (HTTPS) |
|
|
| Auth | Test accounts | Real users |
|
|
| Data | Test/mock data | Real data |
|
|
|
|
## 🚨 Critical Information for MCP Session
|
|
|
|
**Working Directory:** `/Users/tillschneider/Documents/__00__Code/uload`
|
|
|
|
**PocketBase Location:** `backend/pocketbase`
|
|
|
|
**Admin Credentials:**
|
|
- Email: `till.schneider@memoro.ai`
|
|
- Password: `p0ck3t-RAJ`
|
|
|
|
**Collections to Create (in order):**
|
|
1. accounts (optional, but create first if needed)
|
|
2. links
|
|
3. clicks
|
|
|
|
**After Creation:**
|
|
1. Run: `node scripts/seed-local-db.js`
|
|
2. Test at: http://localhost:5173
|
|
|
|
---
|
|
|
|
This documentation contains everything needed to complete the PocketBase setup in a new session with MCP tools. The environment is prepared and only needs the collections to be created. |