Skip to content

Latest commit

ย 

History

History
591 lines (446 loc) ยท 15.7 KB

File metadata and controls

591 lines (446 loc) ยท 15.7 KB

Architecture Documentation

This document provides detailed technical information about the Petitions by BetterGov.ph platform architecture, database design, and development workflows.

๐Ÿ—๏ธ System Architecture

Frontend Architecture

  • Framework: React 19 with TypeScript
  • Build Tool: Vite for fast development and optimized builds
  • Styling: Tailwind CSS with custom components
  • State Management: React hooks and context for local state
  • Routing: React Router for client-side navigation
  • Forms: Custom form handling with validation
  • Editor: @uiw/react-md-editor for rich text content

Backend Architecture

  • Runtime: Cloudflare Workers/Pages Functions
  • Database: Cloudflare D1 (SQLite-based)
  • Caching: Cloudflare KV for performance optimization
  • Authentication: Auth.js (NextAuth) integration
  • File Storage: Base64 encoding for images (small files)
  • API Design: RESTful endpoints with TypeScript

Infrastructure

  • Hosting: Cloudflare Pages
  • CDN: Cloudflare global network
  • Database: Cloudflare D1 with automatic backups
  • Caching: Multi-layer caching (KV, browser, CDN)
  • Security: HTTPS, CORS, input validation

๐Ÿ“Š Database Schema

Core Tables

Users

CREATE TABLE users (
  id TEXT PRIMARY KEY,           -- Auth.js compatible TEXT ID
  name TEXT,                     -- Auth.js user name field
  email TEXT UNIQUE NOT NULL,    -- Auth.js email field
  emailVerified TEXT,            -- Auth.js email verification
  image TEXT,                    -- Auth.js user image field
  createdAt TEXT DEFAULT CURRENT_TIMESTAMP,
  updatedAt TEXT DEFAULT CURRENT_TIMESTAMP
);

Petitions

CREATE TABLE petitions (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  title TEXT NOT NULL,
  description TEXT NOT NULL,
  type TEXT CHECK(type IN ('local', 'national')) NOT NULL,
  image_url TEXT,
  target_count INTEGER NOT NULL DEFAULT 1000,
  current_count INTEGER DEFAULT 0,
  status TEXT CHECK(status IN ('active', 'completed', 'closed')) DEFAULT 'active',
  location TEXT,                 -- for local petitions
  due_date DATETIME NOT NULL,
  slug TEXT UNIQUE NOT NULL,
  published_at DATETIME,         -- NULL if unpublished
  private BOOLEAN DEFAULT FALSE,
  created_by TEXT NOT NULL,      -- References users(id)
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (created_by) REFERENCES users(id)
);

Signatures

CREATE TABLE signatures (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  petition_id INTEGER NOT NULL,
  user_id TEXT NOT NULL,        -- References users(id)
  comment TEXT,
  anonymous BOOLEAN DEFAULT FALSE,
  ip_address TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  FOREIGN KEY (petition_id) REFERENCES petitions(id) ON DELETE CASCADE,
  FOREIGN KEY (user_id) REFERENCES users(id),
  UNIQUE(petition_id, user_id)  -- Prevent duplicate signatures
);

Categories

CREATE TABLE categories (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  name TEXT UNIQUE NOT NULL,
  description TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

Petition Categories (Junction Table)

CREATE TABLE petition_categories (
  petition_id INTEGER,
  category_id INTEGER,
  PRIMARY KEY (petition_id, category_id),
  FOREIGN KEY (petition_id) REFERENCES petitions(id) ON DELETE CASCADE,
  FOREIGN KEY (category_id) REFERENCES categories(id) ON DELETE CASCADE
);

Indexes

-- Performance indexes
CREATE INDEX idx_petitions_status ON petitions(status);
CREATE INDEX idx_petitions_created_at ON petitions(created_at);
CREATE INDEX idx_petitions_slug ON petitions(slug);
CREATE INDEX idx_petitions_published_at ON petitions(published_at);
CREATE INDEX idx_petitions_private ON petitions(private);
CREATE INDEX idx_petitions_created_by ON petitions(created_by);
CREATE INDEX idx_signatures_petition_id ON signatures(petition_id);
CREATE INDEX idx_signatures_user_id ON signatures(user_id);
CREATE INDEX idx_signatures_created_at ON signatures(created_at);

๐Ÿ”ง Development Setup

Prerequisites

Detailed Setup

1. Install Wrangler CLI

npm install -g wrangler
wrangler login  # Optional for local development

2. Database Setup

# Create local D1 database
npm run db:create

# Run migrations and seed data
npm run db:setup

# Verify setup
wrangler d1 execute petition-db --local --command "SELECT COUNT(*) FROM petitions"

3. Environment Configuration

Create a .dev.vars file for local development:

# Add any environment variables here
# DATABASE_URL is handled by Wrangler automatically

Update wrangler.toml with your database ID if needed:

[[d1_databases]]
binding = "DB"
database_name = "petition-db"
database_id = "your-database-id-here"  # Replace with actual ID

Database Management

Local D1 Operations

# Execute SQL commands locally
wrangler d1 execute petition-db --local --command "SELECT * FROM petitions LIMIT 5"

# Execute SQL file locally
wrangler d1 execute petition-db --local --file=./custom-query.sql

# Start D1 console (interactive)
wrangler d1 execute petition-db --local

# View local D1 data location
ls -la .wrangler/state/d1/

Database Maintenance

# Check table structure
wrangler d1 execute petition-db --local --command "PRAGMA table_info(petitions)"

# Count records in each table
wrangler d1 execute petition-db --local --command "
SELECT
  'users' as table_name, COUNT(*) as count FROM users
UNION ALL
SELECT
  'petitions', COUNT(*) FROM petitions
UNION ALL
SELECT
  'signatures', COUNT(*) FROM signatures
UNION ALL
SELECT
  'categories', COUNT(*) FROM categories"

# Reset database (drops all data)
wrangler d1 execute petition-db --local --command "
DROP TABLE IF EXISTS petition_categories;
DROP TABLE IF EXISTS signatures;
DROP TABLE IF EXISTS petitions;
DROP TABLE IF EXISTS users;
DROP TABLE IF EXISTS categories;"

Backup and Restore

# Backup local database
cp .wrangler/state/d1/*.sqlite3 backup/

# Export data to SQL
wrangler d1 export petition-db --local --output backup.sql

# Reset local database completely
rm -rf .wrangler/state/d1/
npm run db:setup

๐Ÿš€ Deployment

Production Deployment to Cloudflare Pages

1. Create Production Database

wrangler d1 create petition-db-prod

2. Update Configuration

Update wrangler.toml with production database ID:

[[d1_databases]]
binding = "DB"
database_name = "petition-db-prod"
database_id = "your-production-database-id"

3. Run Production Migrations

wrangler d1 execute petition-db-prod --file=./db/migrations/consolidated_setup.sql

4. Deploy Application

npm run build
wrangler pages deploy dist

Environment-Specific Configuration

  • Local: Uses .wrangler/state/d1/ SQLite files
  • Production: Uses Cloudflare D1 service
  • Staging: Can use separate D1 database for testing

๐Ÿงช Testing

End-to-End Testing with Playwright

Test Coverage

  • โœ… Petition browsing and listing
  • โœ… Petition detail pages with meta tags
  • โœ… Petition creation (all form features)
  • โœ… Petition signing (named, anonymous, with comments)
  • โœ… Full user workflows
  • โœ… Responsive design testing
  • โœ… Performance testing

Running Tests

# Install Playwright browsers (first time)
npx playwright install

# Run all tests
npm run test:e2e

# Run with browser UI
npm run test:e2e:ui

# Run specific test file
npx playwright test petitions.spec.ts

# Run tests in headed mode
npm run test:e2e:headed

# Debug tests
npx playwright test --debug

Test Configuration

See playwright.config.ts for detailed test configuration including:

  • Browser settings (Chromium, Firefox, WebKit)
  • Viewport configurations
  • Test timeouts
  • Base URL configuration
  • Screenshot and video settings

๐Ÿ“ Project Structure

petition/
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ components/              # React components
โ”‚   โ”‚   โ”œโ”€โ”€ ui/                 # Reusable UI components (Button, Card, etc.)
โ”‚   โ”‚   โ”œโ”€โ”€ auth/               # Authentication components
โ”‚   โ”‚   โ”œโ”€โ”€ layout/             # Layout components (Navbar, Footer)
โ”‚   โ”‚   โ”œโ”€โ”€ shared/             # Shared components (PetitionCard)
โ”‚   โ”‚   โ”œโ”€โ”€ PetitionDetail.tsx  # Individual petition page
โ”‚   โ”‚   โ”œโ”€โ”€ CreatePetition.tsx  # Petition creation form
โ”‚   โ”‚   โ”œโ”€โ”€ EditPetition.tsx    # Petition editing form
โ”‚   โ”‚   โ”œโ”€โ”€ ReviewPetition.tsx  # Petition review before publishing
โ”‚   โ”‚   โ”œโ”€โ”€ SignPetitionModal.tsx # Petition signing modal
โ”‚   โ”‚   โ””โ”€โ”€ UserProfile.tsx     # User profile and dashboard
โ”‚   โ”œโ”€โ”€ contexts/               # React contexts
โ”‚   โ”‚   โ”œโ”€โ”€ ModalContext.tsx    # Modal management
โ”‚   โ”‚   โ””โ”€โ”€ AuthContext.tsx     # Authentication state
โ”‚   โ”œโ”€โ”€ hooks/                  # Custom React hooks
โ”‚   โ”‚   โ”œโ”€โ”€ useAuth.tsx         # Authentication hook
โ”‚   โ”‚   โ””โ”€โ”€ useUserSignatures.tsx # User signatures management
โ”‚   โ”œโ”€โ”€ services/               # API and external services
โ”‚   โ”‚   โ””โ”€โ”€ api.ts              # API client with caching
โ”‚   โ”œโ”€โ”€ types/                  # TypeScript type definitions
โ”‚   โ”‚   โ””โ”€โ”€ api.ts              # API response types
โ”‚   โ”œโ”€โ”€ db/                     # Database related files
โ”‚   โ”‚   โ”œโ”€โ”€ migrations/         # Database migration files
โ”‚   โ”‚   โ”œโ”€โ”€ seeds/              # Database seed data
โ”‚   โ”‚   โ”œโ”€โ”€ schemas/            # Database schema definitions
โ”‚   โ”‚   โ””โ”€โ”€ service.ts          # Database service layer
โ”‚   โ””โ”€โ”€ utils/                  # Utility functions
โ”œโ”€โ”€ functions/                   # Cloudflare Pages Functions
โ”‚   โ”œโ”€โ”€ api/                    # API route handlers
โ”‚   โ”‚   โ”œโ”€โ”€ petitions/          # Petition-related endpoints
โ”‚   โ”‚   โ”œโ”€โ”€ petition/           # Individual petition endpoints
โ”‚   โ”‚   โ”œโ”€โ”€ signatures/         # Signature endpoints
โ”‚   โ”‚   โ”œโ”€โ”€ categories/         # Category endpoints
โ”‚   โ”‚   โ””โ”€โ”€ users/              # User endpoints
โ”‚   โ”œโ”€โ”€ auth/                   # Authentication endpoints
โ”‚   โ””โ”€โ”€ _shared/                # Shared utilities for functions
โ”œโ”€โ”€ tests/                      # Test files
โ”‚   โ”œโ”€โ”€ e2e/                    # Playwright E2E tests
โ”‚   โ””โ”€โ”€ README.md               # Testing documentation
โ”œโ”€โ”€ public/                     # Static assets
โ”‚   โ”œโ”€โ”€ logos/                  # Logo files
โ”‚   โ””โ”€โ”€ locales/                # Internationalization files
โ”œโ”€โ”€ wrangler.toml               # Cloudflare configuration
โ”œโ”€โ”€ playwright.config.ts        # Playwright test configuration
โ”œโ”€โ”€ tailwind.config.js          # Tailwind CSS configuration
โ”œโ”€โ”€ vite.config.ts              # Vite build configuration
โ””โ”€โ”€ tsconfig.json               # TypeScript configuration

๐ŸŽจ Key Components

CreatePetition Component

Features:

  • Card-based petition type selection (Local vs National)
  • Rich markdown editor for descriptions
  • Base64 image upload with preview
  • Category selection with tag display
  • Form validation and error handling
  • Location input for local petitions
  • Target signature count setting

Technical Details:

  • Uses @uiw/react-md-editor for markdown editing
  • Implements custom image upload with base64 encoding
  • Form state management with React hooks
  • Real-time validation feedback

PetitionDetail Component

Features:

  • SEO-optimized meta tags with Open Graph support
  • Progress tracking with visual progress bars
  • Recent signatures list with pagination
  • Social sharing functionality
  • Sign petition modal integration
  • Responsive design for all devices

Technical Details:

  • React Suspense for loading states
  • Dynamic meta tag generation for SEO
  • Cache-busting for real-time updates
  • Optimistic UI updates for signatures

SignPetitionModal Component

Features:

  • Form validation with real-time feedback
  • Anonymous signing option
  • Comment support with character counting
  • Duplicate signature prevention
  • Success/error state handling

Technical Details:

  • Modal state management with context
  • Form validation with custom hooks
  • API integration with error handling

๐Ÿ”ง Performance Optimizations

Caching Strategy

Cloudflare KV Caching

  • Petition Lists: Cached for 5 minutes
  • Individual Petitions: Cached for 2 minutes
  • User Signatures: Cached for 1 minute
  • Categories: Cached for 1 hour

Cache Invalidation

  • Automatic invalidation on data changes
  • Pattern-based cache clearing
  • Manual cache refresh options

Client-Side Caching

  • Cookie-based user signature caching
  • Browser cache optimization
  • Service worker for offline support (future)

Database Optimizations

  • Strategic indexing for common queries
  • Efficient JOIN operations
  • Pagination for large datasets
  • Connection pooling

๐Ÿ”’ Security Considerations

Input Validation

  • Server-side validation for all inputs
  • SQL injection prevention
  • XSS protection with content sanitization
  • CSRF protection

Authentication & Authorization

  • Secure session management
  • Role-based access control
  • Rate limiting for API endpoints
  • IP-based restrictions for sensitive operations

Data Privacy

  • Anonymous signature options
  • GDPR compliance considerations
  • Data retention policies
  • Secure data transmission (HTTPS)

๐Ÿ› Troubleshooting

Common Development Issues

Database Issues

Database not found:

# Recreate local database
wrangler d1 create petition-db --local
npm run db:setup

Migration errors:

# Reset and re-run migrations
rm -rf .wrangler/state/d1/
npm run db:setup

Build Issues

Wrangler not found:

# Install globally
npm install -g wrangler
# Or use npx
npx wrangler login

Build errors:

# Clean install
rm -rf node_modules package-lock.json
npm install

Test Issues

Tests failing:

# Install Playwright browsers
npx playwright install
# Ensure dev server is running
npm run dev  # In separate terminal

Performance Issues

Slow database queries:

  • Check indexes are properly created
  • Analyze query execution plans
  • Consider query optimization

Slow page loads:

  • Check caching configuration
  • Optimize image sizes
  • Review bundle size

๐Ÿ“ˆ Monitoring & Analytics

Performance Monitoring

  • Cloudflare Analytics for traffic insights
  • Core Web Vitals tracking
  • Database query performance
  • API response times

Error Tracking

  • Console error logging
  • API error monitoring
  • User feedback collection
  • Performance bottleneck identification

๐Ÿ”ฎ Future Enhancements

Planned Features

  • Multi-language Support: Full i18n implementation
  • Advanced Analytics: Detailed petition performance metrics
  • Email Notifications: Automated updates for petition creators
  • Mobile App: React Native mobile application
  • API v2: GraphQL API for better performance
  • Advanced Moderation: AI-powered content moderation

Technical Improvements

  • Service Worker: Offline support and caching
  • WebSockets: Real-time signature updates
  • CDN Optimization: Image optimization and delivery
  • Database Sharding: Horizontal scaling for large datasets
  • Microservices: Service-oriented architecture

This architecture documentation is maintained alongside the codebase. For questions or clarifications, please refer to the GitHub Discussions.