Skip to content

Latest commit

Β 

History

177 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

BookBridge πŸ“š

Flutter Supabase SvelteKit License: MIT Platform Version

A Social Venture to End Learning Poverty in Cameroon

BookBridge is a peer-to-peer marketplace designed for Cameroonian students to buy and sell used physical books. Powered by Flutter and Supabase, it facilitates affordable access to textbooks and educational resources while enabling students to recycle and monetize their book collections.

Our Mission: To democratize access to education in Cameroon, addressing the crisis where 72% of children cannot read and understand simple text by age 10.


πŸ“Έ Screenshots

Screenshot 1 Screenshot 2 Screenshot 3

🌟 Key Features

Core Marketplace

  • User Authentication: Secure sign-in and profile synchronization via Supabase Auth.
  • Smart Search: Full-text indexing across book titles and authors using PostgreSQL tsvector with relevance ranking.
  • Direct Handover Flow: Intuitive purchase flow featuring user-to-user coordination.
  • Category Filtering: Browse books by category (textbooks, novels, references, etc.) with responsive chips.
  • Secure Storage: Public book cover images hosted securely via bucket policies in Supabase Storage.

Automated Escrow System (MoMo Integration)

  • Secure Holds: Funds are collected via Fapshi Direct Pay (MoMo/Orange Money) and held in escrow until the buyer confirms physical handover.
  • 5-Day Auto-Release: Prevents sellers from being ghosted. Escrows are automatically released to the seller after 5 days if no dispute is filed.
  • Status Polling: A pg_cron background worker Edge Function checks payment status every 5 minutes to automatically resolve transactions stuck in pending_payment.
  • Dispute Freeze: Buyers can report problems to freeze the auto-release timer and trigger admin review.
  • Secure Payouts: Payout execution is handled entirely server-side (Edge Functions) using database secrets via app_secrets (RLS enforced).
  • Audit Logging: Every API transaction with Fapshi is logged in fapshi_audit_logs for transaction history, tracing, and fraud prevention.

πŸ—οΈ Architecture

BookBridge follows Clean Architecture patterns separating business logic, UI, and data layers:

lib/
β”œβ”€β”€ core/                      # Shared assets, utilities, and components
β”‚   β”œβ”€β”€ error/                # Functional error handling (Failures, Exceptions)
β”‚   β”œβ”€β”€ theme/                # Custom Material Design 3 theme
β”‚   └── usecases/             # Base abstract UseCase contracts
β”œβ”€β”€ features/                 # Modules encapsulating distinct functionality
β”‚   β”œβ”€β”€ auth/                 # Domain, data, and presentation layers for Auth
β”‚   β”œβ”€β”€ chat/                 # Real-time message exchange
β”‚   β”œβ”€β”€ favorites/            # Wishlists and saved listings
β”‚   β”œβ”€β”€ listings/             # Browsing, listing creation, and category search
β”‚   β”œβ”€β”€ payments/             # Fapshi Direct Pay integration & ViewModels
β”‚   β”œβ”€β”€ reviews/              # Buyer/Seller trust rating system
β”‚   └── transactions/         # Escrow confirm and dispute handlers
β”œβ”€β”€ config/                   # Global configuration
β”‚   β”œβ”€β”€ app_config.dart      # Dart define environment bindings
β”‚   └── router.dart          # Route configurations (go_router)
β”œβ”€β”€ injection_container.dart  # GetIt dependency injection setup
└── main.dart                # Application entry point

Escrow Architecture Sequence

sequenceDiagram
    actor Buyer
    actor Seller
    participant App as Flutter Mobile App
    participant Fapshi as Fapshi API
    participant Webhook as SvelteKit Webhook
    participant DB as Supabase DB
    participant Cron as pg_cron / Edge Functions

    Buyer->>App: Clicks "Buy Now" & enters MoMo details
    App->>Fapshi: Direct Pay request
    Fapshi-->>App: Returns transId (CREATED)
    Fapshi->>Webhook: Webhook notification (CREATED/PENDING)
    Webhook->>DB: Inserts transaction as 'pending_payment'
    Buyer->>Fapshi: Approves USSD Push (MoMo Payment)
    Fapshi->>Webhook: Webhook notification (SUCCESSFUL)
    Webhook->>DB: Updates transaction status to 'held' & creates escrow
    Webhook->>DB: Marks listing as 'sold'
    Note over DB: 5-Day Auto-Release timer starts
    Seller->>Buyer: Hands over physical book
    alt Buyer Confirms Delivery
        Buyer->>App: Clicks "Confirm Receipt"
        App->>Cron: Calls process-escrow Edge Function (release)
    else Cooldown Expired (5 days)
        Cron->>DB: Auto-release-expired job triggers
    end
    Cron->>Fapshi: Payout API request to Seller
    Fapshi-->>Cron: Payout SUCCESSFUL
    Cron->>DB: Updates status to 'released' and payout successful
    DB->>Seller: MoMo Payout Received
Loading

πŸš€ Getting Started

Prerequisites

  • Flutter SDK (v3.10.7 or higher)
  • Supabase CLI / Account
  • Node.js (for SvelteKit Landing Page)

Repository Setup

  1. Clone the project:
    git clone https://github.com/DCT-Berinyuy/book-bridge.git
    cd book-bridge
  2. Fetch packages:
    flutter pub get

Configuration

Create a .env file in the project root:

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key
FAPSHI_API_USER=your-fapshi-user
FAPSHI_API_KEY=your-fapshi-key
FAPSHI_BASE_URL=https://live.fapshi.com

Launching the App

Run the application with environments injected using --dart-define:

flutter run \
  --dart-define="SUPABASE_URL=$(grep SUPABASE_URL .env | cut -d'=' -f2)" \
  --dart-define="SUPABASE_ANON_KEY=$(grep SUPABASE_ANON_KEY .env | cut -d'=' -f2)" \
  --dart-define="FAPSHI_API_USER=$(grep FAPSHI_API_USER .env | cut -d'=' -f2)" \
  --dart-define="FAPSHI_API_KEY=$(grep FAPSHI_API_KEY .env | cut -d'=' -f2)"

Running Landing Page (SvelteKit)

cd landingPage
npm install
npm run dev

πŸ“Š Database Schema Highlights

transactions Table

Stores buyer purchase logs and commissions.

CREATE TABLE public.transactions (
    id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    listing_id UUID NOT NULL REFERENCES public.listings(id) ON DELETE CASCADE,
    buyer_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    seller_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    amount INTEGER NOT NULL CHECK (amount > 0),
    payment_reference TEXT UNIQUE NOT NULL,
    status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'pending_payment', 'successful', 'failed', 'held', 'disputed')),
    payout_status TEXT DEFAULT 'pending',
    payout_reference TEXT,
    commission_amount INTEGER,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

escrow_transactions Table

Manages the auto-release deadline timer.

CREATE TABLE public.escrow_transactions (
  id               UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  transaction_id   UUID NOT NULL REFERENCES public.transactions(id) ON DELETE CASCADE,
  status           TEXT NOT NULL DEFAULT 'held' CHECK (status IN ('held', 'released', 'refunded', 'disputed')),
  dispute_reason   TEXT,
  created_at       TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at       TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  release_deadline TIMESTAMP WITH TIME ZONE GENERATED ALWAYS AS (public.add_5_days(created_at)) STORED
);

fapshi_audit_logs Table

Maintains payout auditing logs for administrative review.

CREATE TABLE public.fapshi_audit_logs (
  id               UUID DEFAULT gen_random_uuid() PRIMARY KEY,
  transaction_id   UUID REFERENCES public.transactions(id) ON DELETE SET NULL,
  endpoint         TEXT NOT NULL,
  request_payload  JSONB,
  response_payload JSONB,
  status_code      INTEGER,
  created_at       TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

🧭 Navigation & Routes

The application leverages go_router supporting authentication redirects and shell layouts:

Route Screen Auth? Description
/ SplashScreen No Sessions startup and auth routing
/sign-in SignInScreen No User login portal
/home HomeScreen Yes Browse books listings feed
/search SearchScreen Yes Run FTS indexing search queries
/sell SellScreen Yes Book details registration and storage uploads
/profile ProfileScreen Yes User details, feedback, and active listings
/listing/:id ListingDetailsScreen Yes Specific book details & checkout portal

🀝 Contributing Guidelines

  1. Fork the Repository.
  2. Create a Feature Branch (git checkout -b feature/AmazingFeature).
  3. Follow the Clean Architecture design rules.
  4. Ensure files are properly formatted:
    dart format .
    flutter analyze
  5. Commit your Changes (git commit -m 'feat: Add AmazingFeature').
  6. Push to Branch (git push origin feature/AmazingFeature).
  7. Open a Pull Request.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


Made with ❀️ for Cameroonian students
Democratizing access to knowledge, one book at a time.

About

A peer-to-peer marketplace for Cameroonian students to buy and sell used physical books

Topics

Resources

Stars

7 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages