Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
DATABASE_URL=postgresql://user:password@localhost:5432/hackvillage

PAYSTACK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=pk_test_...

SMART_CONTRACT_ADDRESS=0x...
RPC_URL=https://rpc-amoy.polygon.technology

NEXTAUTH_SECRET=replace-with-a-long-random-string
NEXTAUTH_URL=http://localhost:3000
11 changes: 11 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
node_modules
.next
frontend/.next
out
coverage
public/sw.js
public/workbox-*.js
public/swe-worker-*.js
frontend/public/sw.js
frontend/public/workbox-*.js
frontend/public/swe-worker-*.js
8 changes: 8 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "next/core-web-vitals",
"settings": {
"next": {
"rootDir": "frontend/"
}
}
}
55 changes: 55 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/frontend/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem
Thumbs.db

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# env files
.env
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

# PWA
public/sw.js
public/sw.js.map
public/workbox-*.js
public/workbox-*.js.map
public/swe-worker-*.js
public/swe-worker-*.js.map
frontend/public/sw.js
frontend/public/sw.js.map
frontend/public/workbox-*.js
frontend/public/workbox-*.js.map
frontend/public/swe-worker-*.js
frontend/public/swe-worker-*.js.map

# prisma
prisma/*.db
prisma/*.db-journal
8 changes: 8 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
.next
out
coverage
package-lock.json
public/sw.js
public/workbox-*.js
public/swe-worker-*.js
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"semi": true,
"singleQuote": false,
"trailingComma": "all",
"printWidth": 90
}
47 changes: 30 additions & 17 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,21 +142,34 @@ Open [http://localhost:3000](http://localhost:3000) in your browser.

```
HackVillage/
├── app/ # Next.js App Router — pages and layouts
├── components/ # Shared React components
├── lib/ # Shared utilities, DB client, API helpers
├── services/
│ ├── escrow/ # Escrow microservice — Paystack + smart contract calls
│ └── payout/ # Split disbursement logic
├── contracts/ # Smart contract source and ABI
├── db/
│ ├── migrations/ # PostgreSQL migrations
│ └── seeds/ # Seed data for development
├── public/ # Static assets
└── tests/ # Unit and integration tests
├── frontend/ # Next.js UI + Route Handlers (App Router)
│ ├── app/ # Pages, layouts, PWA manifest, API routes
│ ├── components/ # Shared React components
│ └── public/ # Static assets & PWA icons
├── backend/ # Domain logic, data, and financial engines
│ ├── services/
│ │ ├── escrow/ # Escrow — Paystack + smart contract calls
│ │ └── payout/ # Split disbursement logic
│ ├── contracts/ # Smart contract source and ABI
│ ├── lib/ # DB client, env helpers
│ ├── prisma/ # Prisma schema
│ └── db/
│ ├── migrations/ # PostgreSQL migrations
│ └── seeds/ # Seed data for development
└── tests/ # Unit and integration tests
```

Changes to `services/escrow/` and `contracts/` carry the highest risk and require the most thorough review. See [Working with the Escrow Layer](#working-with-the-escrow-layer) before touching those areas.
**Where to contribute**

| Area | Work in |
|---|---|
| Pages, UI, PWA, Route Handlers | `frontend/` |
| Escrow, payouts, Prisma, seeds | `backend/` |
| Tests | `tests/` (mirror backend service names) |

Import backend modules from the frontend with `@backend/...` (e.g. `@backend/services/escrow`).

Changes to `backend/services/escrow/`, `backend/services/payout/`, and `backend/contracts/` carry the highest risk and require the most thorough review. See [Working with the Escrow Layer](#working-with-the-escrow-layer) before touching those areas.

---

Expand Down Expand Up @@ -256,7 +269,7 @@ Before marking your PR ready for review, confirm:

### General

- **TypeScript everywhere** — No plain `.js` files in `app/`, `components/`, `lib/`, or `services/`.
- **TypeScript everywhere** — No plain `.js` files in `frontend/` or `backend/`.
- **Strict mode** — `"strict": true` in `tsconfig.json`. Do not disable strict checks.
- **No `any`** — Use proper types. If the type is genuinely unknown, use `unknown` and narrow it.
- **Named exports** — Prefer named exports over default exports for better refactoring support.
Expand Down Expand Up @@ -299,7 +312,7 @@ npm run test:e2e # End-to-end tests (requires running dev server)

### Requirements

- Every new function in `services/escrow/` and `services/payout/` must have unit tests.
- Every new function in `backend/services/escrow/` and `backend/services/payout/` must have unit tests.
- Payout failure and rollback paths must be covered — these are the highest-risk code paths.
- Integration tests for Paystack interactions must use Paystack's test mode with recorded fixtures; they must not make live network calls in CI.
- Smart contract tests must run against a local hardhat or anchor test node, not a public testnet.
Expand All @@ -308,13 +321,13 @@ npm run test:e2e # End-to-end tests (requires running dev server)

## Working with the Escrow Layer

The escrow and payout engine (`services/escrow/`, `services/payout/`, `contracts/`) is the most sensitive part of the codebase. Bugs here can result in funds being locked permanently or paid out incorrectly. Before contributing to these areas:
The escrow and payout engine (`backend/services/escrow/`, `backend/services/payout/`, `backend/contracts/`) is the most sensitive part of the codebase. Bugs here can result in funds being locked permanently or paid out incorrectly. Before contributing to these areas:

1. **Read the architecture section** in the README in full.
2. **Open an issue first** for any non-trivial change, even if it looks like a fix. Describe the current behavior, the desired behavior, and your proposed approach. Wait for maintainer acknowledgment before writing code.
3. **Never remove or weaken rollback logic.** If a Paystack call fails or a network error occurs, funds must remain locked in the vault. This is a hard invariant.
4. **Smart contract changes require a testnet deployment** and a link to the verified contract in the PR description before review will begin.
5. **Two maintainer approvals** are required to merge any PR that touches `services/escrow/`, `services/payout/`, or `contracts/`.
5. **Two maintainer approvals** are required to merge any PR that touches `backend/services/escrow/`, `backend/services/payout/`, or `backend/contracts/`.

---

Expand Down
56 changes: 49 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<img src="https://www.technetium.co.ke/assets/images/logo.webp" alt="Technetium Kenya" height="60" />
&nbsp;&nbsp;&nbsp;&nbsp;
<img src="./public/images/salamander-logo-yellow.svg" alt="HackVillage" height="60" />
<img src="./frontend/public/images/salamander-logo-yellow.svg" alt="HackVillage" height="60" />
</div>

<br />
Expand Down Expand Up @@ -153,9 +153,9 @@ HackVillage operates as a three-phase engine:

| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Next.js 14 | SEO-optimized project discovery |
| Backend | Node.js / TypeScript | High-concurrency event-day API |
| Database | PostgreSQL | Structured Proof of Work records |
| Frontend | Next.js 14 + PWA | SEO-optimized discovery; installable app |
| Backend | Node.js / TypeScript (`backend/`) | Escrow, payouts, Prisma domain services |
| Database | PostgreSQL + Prisma | Structured Proof of Work records |
| Payments | Paystack | Fiat deposits, M-Pesa & bank payouts |
| Ledger | Smart Contract (Polygon/Solana) | Transparent, tamper-proof transaction log |
| Open Source Core | GitHub | Judging logic & escrow mechanics are public |
Expand Down Expand Up @@ -247,36 +247,76 @@ Paystack API ──── Final transfer ──── Public Ledger entry record
- PostgreSQL >= 15
- A Paystack account (test keys sufficient for local development)

### Repository layout

The codebase is split so frontend and backend contributors can work in parallel:

```
HackVillage/
├── frontend/ # Next.js 14 App Router UI + PWA + Route Handlers
├── backend/ # Prisma/PostgreSQL, escrow & payout services, ledger stubs
└── tests/ # Unit tests (vitest)
```

| Area | Docs |
|---|---|
| UI / PWA | [frontend/README.md](./frontend/README.md) |
| Data / escrow / payouts | [backend/README.md](./backend/README.md) |
| Contributions | [CONTRIBUTING.md](./CONTRIBUTING.md) |

Still a **single npm package** — install and run everything from the repo root.

### Installation

```bash
git clone https://github.com/CodeWithEugene/HackVillage.git
git clone https://github.com/Salamander-Tech-Hub/HackVillage.git
cd HackVillage
npm install
cp .env.example .env.local
```

### Environment Variables

Create a `.env.local` file at the project root:
Create a `.env.local` file at the project root (see `.env.example`):

```env
DATABASE_URL=postgresql://user:password@localhost:5432/hackvillage
PAYSTACK_SECRET_KEY=sk_test_...
NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY=pk_test_...
SMART_CONTRACT_ADDRESS=0x...
RPC_URL=https://...
NEXTAUTH_SECRET=replace-with-a-long-random-string
NEXTAUTH_URL=http://localhost:3000
```

### Development

```bash
npm run db:migrate
npm run db:seed # optional — demo organizer + Prize Verified event
npm run dev
```

Open [http://localhost:3000](http://localhost:3000) in your browser.

Useful scripts:

| Command | Purpose |
|---|---|
| `npm run dev` | Next.js dev server (`./frontend`) |
| `npm run build` | Production build (enables PWA service worker) |
| `npm run db:migrate` / `db:seed` / `db:studio` | Prisma against `backend/prisma/schema.prisma` |
| `npm test` | Unit tests |
| `npm run typecheck` / `npm run lint` | CI-style checks |

### Progressive Web App

HackVillage is installable as a PWA (manifest + service worker). The service worker is **disabled in development** and generated on production builds — use `npm run build && npm start` to verify install / offline behavior (`/offline` fallback).

### Database

Prisma schema lives at `backend/prisma/schema.prisma` and models events, escrow vaults, payouts, submissions, judging, and developer profiles.

```bash
npm run db:migrate
npm run db:seed # optional — seeds demo events and profiles
Expand All @@ -295,6 +335,8 @@ HackVillage is open-source at its core. The judging logic and escrow mechanics a

Please read `CONTRIBUTING.md` before submitting a PR. All contributors are expected to uphold the [Code of Conduct](CODE_OF_CONDUCT.md).

UI work lives under `frontend/`; escrow, payouts, and schema changes live under `backend/`. Import backend modules from the app with `@backend/...`.

---

## License
Expand All @@ -307,6 +349,6 @@ This project is licensed under the [MIT License](./LICENSE).

Built with intention for the African developer community.

**[technetium.co.ke](https://www.technetium.co.ke)** &nbsp;·&nbsp; **[github.com/CodeWithEugene/HackVillage](https://github.com/CodeWithEugene/HackVillage)**
**[technetium.co.ke](https://www.technetium.co.ke)** &nbsp;·&nbsp; **[github.com/Salamander-Tech-Hub/HackVillage](https://github.com/Salamander-Tech-Hub/HackVillage)**

</div>
Loading