GovBot Web Application
A decentralized governance platform for managing proposals and grants on the Mina Protocol blockchain. Built with Next.js 14, TypeScript, and Prisma.
Features
- π Multi-source authentication (Discord, Telegram, Wallet)
- π Account linking across auth providers
- π Proposal creation and management
- π¨ Modern UI with shadcn/ui components
- π Server-side rendering with Next.js
- π Type-safe database operations with Prisma
- π³ Docker support for development
Tech Stack
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- Database: PostgreSQL 17
- ORM: Prisma
- UI: shadcn/ui + Tailwind CSS
- Authentication: Custom JWT implementation
- Container: Docker + Docker Compose
Getting Started
Prerequisites
- Node.js 18+
- Docker and Docker Compose
- npm
Environment Setup
Create a .env
file in the root directory:
JWT_PRIVATE_KEY_RS512="-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----"
JWT_PUBLIC_KEY_RS512="-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----"
# PGAdmin Configuration
PGADMIN_EMAIL=admin@example.com
PGADMIN_PASSWORD=pgadmin_password
# Database Configuration
POSTGRES_DB=govbot
POSTGRES_PASSWORD=your_secure_password_here
DATABASE_URL="postgresql://postgres:your_secure_password_here@db:5432/govbot?schema=public"
Development with Docker
- Start the development environment:
docker-compose up
This will start:
- Access the application:
Local Development
- Install dependencies:
npm install
- Start PostgreSQL:
docker-compose up db
- Run migrations:
npx prisma migrate dev
- Start development server:
npm run dev
OR
docker compose up --build
Architecture
Authentication System
The platform supports multiple authentication sources:
-
Auth Sources:
- Discord (via bot)
- Telegram (via bot)
- Mina Protocol Wallet
-
JWT Implementation:
- Short-lived access tokens (15 minutes)
- Refresh tokens (7 days)
- Secure httpOnly cookies
- Token rotation on refresh
-
User Resolution:
// User ID derivation
userId = UUIDv5(authSource.type + authSource.id);
Account Linking
Users can link multiple authentication sources:
-
Linking Process:
- Each user has a
linkId
- Linked accounts share the same
linkId
- All linked accounts can access shared resources
-
Implementation:
interface User {
id: string; // Derived from auth source
linkId: string; // Shared between linked accounts
metadata: Json; // Auth source info
}
API Routes
Authentication
POST /api/auth/exchange
- Exchange initial token for access/refresh tokens
POST /api/auth/refresh
- Refresh access token
POST /api/auth/logout
- Clear auth tokens
Proposals
GET /api/proposals
- List user's proposals
POST /api/proposals
- Create new proposal
GET /api/proposals/:id
- Get proposal details
PUT /api/proposals/:id
- Update proposal
DELETE /api/proposals/:id
- Delete draft proposal
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
)
- Commit your changes (
git commit -m 'Add amazing feature'
)
- Push to the branch (
git push origin feature/amazing-feature
)
- Open a Pull Request
Development Guidelines
-
TypeScript:
- Enable strict mode
- Use proper type inference
- Define clear interfaces
-
Components:
- Use Server Components by default
- Implement proper error boundaries
- Follow accessibility guidelines
-
Styling:
- Use Tailwind CSS classes
- Follow shadcn/ui patterns
- Maintain consistent theming
Deployment
- Production Build:
npm run build
- Docker Production:
docker-compose -f docker-compose.prod.yml up
Contributing
To contribute, follow these steps:
- Make an issue that includes details about the feature or bug or something else.
- Get that issue tested by: Cristina Echeverry.
- Get that issue approved by the product owners: Cristina Echeverry (CristinaEche) & Illya Gerasymchuk (iluxonchik)
- Write a PR and get it approved by the code owners and Mina devops: Illya Gerasymchuk (developer & code-owner), johnmarcou (Mina devops). Each PR must correspond to an approved issue. By default, PRs should be merged by the PR submitter, though in some cases if changes are needed, they can be merged by code owners.