A comprehensive backend API for managing volunteers, chapters, nonprofits, projects, and sponsors with both REST and GraphQL endpoints.
- Language - TypeScript
- Framework - Express.js
- Database - PostgreSQL (hosted on Supabase)
- ORM - Prisma
- API Types - REST & GraphQL
- Testing - Jest & Supertest
- Code Quality - ESLint, Prettier, Husky
- CI/CD - GitHub Actions
src/
├── api/
│ ├── rest/ # REST API endpoints
│ └── graphql/ # GraphQL schema and resolvers
├── core/
│ ├── services/ # Business logic
│ └── validators/ # Input validation
├── config/ # Database and server configuration
├── middleware/ # Logging, security, and errors
└── app.ts # Main application entry point
tests/
├── unit/ # Unit tests
└── integration/ # Integration tests
prisma/
├── schema.prisma # Database schema
└── migrations/ # Database migrationsnpm installCreate a .env file in the root directory and copy fields from .env.example:
# Database Configuration
DATABASE_URL=your_database_url_here
DIRECT_URL=your_direct_url_here
# Server Configuration
PORT=3000
REST_PORT=3001
GRAPHQL_PORT=3002npx prisma db pull     # Sync schema with database
npx prisma generate    # Generate Prisma client# Start integrated server (both REST & GraphQL)
npm run dev
# Or start servers separately
npm run dev:rest       # REST API only
npm run dev:graphql    # GraphQL API only
npm run dev:both       # Both servers concurrentlyThe servers will be available at:
- Integrated: http://localhost:3001
- REST API: http://localhost:3002
- GraphQL API: http://localhost:3003
npm run test               # Run all tests (Unit &  Integration)
npm run test:coverage      # Generate coverage report for Unit tests only
npm run test:integration   # Integration tests only
npm run test:unit          # Unit tests only
npm run test:watch         # Watch mode for unit testsThe database includes the following main entities:
- chapters - Local H4I chapters
- companies - Companies associated with volunteers, sponsors, & nonprofits
- contacts - Contact information
- locations - Geographic locations
- operations_branches - H4I Branches of the Operations Board
- nonprofits - Partner nonprofit organizations
- roles - All existing roles within the organization
- projects - Development projects for nonprofits
- sponsors - Corporate sponsors
- volunteers - Student and professional volunteers
The database includes the following main relationship tables:
- nonprofit_chapter_project
- sponsor_chapter
- volunteer_assignment
- volunteer_history
- volunteer_role_project
- DO NOT edit schema.prismadirectly in production
- Use Supabase Table Editor for schema changes in production
- Always run npx prisma db pullandnpx prisma generateafter database changes
- This ensures code stays synchronized with the database
Follow the pattern: feature/issue-number-description
- Example: feature/1-add-volunteer-endpoints
- This automatically links branches to GitHub issues
GraphQL endpoint available at /api/graphql with interactive playground.
Example mutation:
mutation {
  addVolunteer(
    volunteer: {
      first_name: "Jane"
      last_name: "Doe"
      email: "[email protected]"
      graduation_date: "2026-06-18"
      volunteer_status: STUDENT
      H4I_email: "[email protected]"
      volunteer_type: CHAPTER
      university_id: "860b69b4-a14e-41d9-a367-2632b342e549"
    }
  )
}More examples available in docs/examples/graphql-examples.md
REST endpoints available at /api/rest following RESTful conventions.
See docs/api/rest-api.md and docs/api/graphql-api.md for complete API documentation.
- 
Service Layer ( src/core/services/)- Create business logic functions
- Use async/await pattern
- Implement proper error handling with try/catch
- Follow existing naming conventions
- Use function declarations and not arrow functions
 
- 
GraphQL ( src/api/graphql/)- Add schema definitions in schemas/
- Implement resolvers in resolvers/
- Export from respective index files
- Update graphql/resolvers.tsandgraphql/schemas.tsafter schema and resolver implementations
 
- Add schema definitions in 
- 
REST ( src/api/rest/)- Add controllers in controllers/
- Define routes in routes/
- Export from respective index files
- Apply validation using Zod validators from core/validators
- Add route in rest/routes.ts
 
- Add controllers in 
- Mock services before importing in tests
- Use describe()blocks for organizing related tests
- Write async test functions
- Follow AAA pattern: Arrange, Act, Assert
- Integration tests should be completely self-contained - each test creates its own data and doesn't depend on other tests
- Examples available in tests/directory