Geev is a decentralized social platform built on the Stellar blockchain that enables users to create giveaways, post help requests, and participate in community-driven mutual aid.
This package is the web application for Geev, built with Next.js, TypeScript, Prisma, and PostgreSQL.
Use this guide to get a full local development environment running, including database migration and seed data.
- Next.js 16 (App Router)
- TypeScript
- Tailwind CSS v4 + shadcn/ui + Radix UI
- Auth.js (NextAuth)
- Prisma 7 + PostgreSQL
- Node.js 20+
- pnpm 10+
- PostgreSQL running locally
From the monorepo root (new.app/):
pnpm installFrom new.app/app/, create .env (or copy .env.example):
cp .env.example .envMinimum required values:
DATABASE_URL=postgresql://geev:bridgelet_pass@localhost:5432/geev
AUTH_SECRET=<random-secret>
NEXTAUTH_SECRET=<random-secret>Generate a strong secret (use the same value for both secrets if you want):
openssl rand -base64 32Run these commands from new.app/app/:
pnpm prisma generate
pnpm prisma migrate deploy
pnpm prisma db seedWhat seeding adds:
- Default user ranks
- Default badges
- 5 dummy users for development login/testing
From new.app/app/:
pnpm devOpen:
In development mode, use the Dev User Switcher (bottom-right) to sign in as a seeded user.
Expected behavior:
- Navbar/sidebar update to authenticated state
- Main content redirects to
/feed
From new.app/app/:
pnpm dev
pnpm build
pnpm start
pnpm lint
pnpm test
pnpm test:watch
pnpm test:coverage
pnpm prisma studioIf you want a clean local database and reseed everything:
pnpm prisma migrate resetThis drops/recreates the schema, reapplies migrations, and runs seed.
DATABASE_URL is required to run Prisma seed:- Ensure
.envexists innew.app/app/and containsDATABASE_URL.
- Ensure
- Auth/session issues:
- Ensure
AUTH_SECRETandNEXTAUTH_SECRETare set.
- Ensure
- Migration errors:
- Confirm PostgreSQL is running and the database in
DATABASE_URLexists.
- Confirm PostgreSQL is running and the database in
- Theme system:
docs/theme.md - Components:
docs/components.md
- Figma UI Kit: https://www.figma.com/design/bx1z49rPLAXSsUSlQ03ElA/Geev-App?node-id=6-192&t=a3DcI1rqYjGvbhBd-0
- App Prototype (Figma): https://www.figma.com/proto/bx1z49rPLAXSsUSlQ03ElA/Geev-App?node-id=6-192&t=Sk47E3cbSLVg2zcA-0&scaling=min-zoom&content-scaling=fixed&page-id=0%3A1&starting-point-node-id=6%3A192&show-proto-sidebar=1
- Project Summary: https://docs.google.com/document/d/1ZEfrbVF_rjJ3GrLYeTxTboRL15dT0kaVyioXrdPpmMU
- Feature Specifications: https://docs.google.com/document/d/1qRyFhhAqBgZU8NtrVmMk6HV2qSi0nb_K3sxrgPaKymI
- Endpoint:
POST /api/analytics/events - Purpose: Track client and server events (page views, post lifecycle, interactions, errors).
Request Body
{
"eventType": "page_view",
"eventData": { "path": "/feed" },
"pageUrl": "https://app.example.com/feed"
}eventTypemust be one of:"page_view""post_created""entry_submitted""like_added""share_clicked""error_occurred"
eventDatais optional JSON metadata (non-PII only).pageUrlis optional; when omitted, the client helper populates it fromwindow.location.href.
Headers
x-user-id(optional) – the authenticated user ID for DAU/attribution. The default client helper will set this when a user is available.
Response
{
"success": true,
"data": { "tracked": true }
}Analytics failures never block product flows; on internal errors the endpoint returns {"tracked": false} but still responds with success: true.
- Endpoint:
GET /api/analytics/metrics - Purpose: Fetch high-level platform metrics over a time window.
Query Params
period(optional):"24h"– last 24 hours"7d"– last 7 days (default)"30d"– last 30 days
Response
{
"success": true,
"data": {
"period": "7d",
"metrics": {
"active_users": 12,
"posts_created": 5,
"entries_submitted": 42,
"page_views": 380
}
}
}active_users– distinct users with at least one tracked event in the period.posts_created– posts created in the period.entries_submitted– number ofentry_submittedevents in the period.page_views– number ofpage_viewevents in the period.
Results are cached in-memory for 5 minutes per period value to reduce load.
A lightweight helper exists at lib/analytics.ts:
import { trackEvent } from '@/lib/analytics';
await trackEvent('page_view', { path: '/feed' });
await trackEvent('post_created', { postId: 'post_123' }, { userId: '1' });Signature:
trackEvent(eventType: string, eventData?: Record<string, any>, options?: { userId?: string })- No-ops on the server, silently swallows network errors on the client.
Privacy guarantees:
- No PII is added on the server;
eventDatashould not include emails, wallet secrets, or other sensitive values. - Anonymous events are supported (no
x-user-id). - Events are used for behavioral and performance insights, not for tracking individual identities beyond an opaque user ID.