Skip to content

Latest commit

 

History

History
552 lines (400 loc) · 20.6 KB

File metadata and controls

552 lines (400 loc) · 20.6 KB

🤝 Contributing to FitMart

First off — thank you for taking the time to contribute! 🎉

Whether you're fixing a bug, adding a feature, improving docs, or just asking a question — every contribution matters and you are welcome here.

This guide will walk you through everything you need to know to contribute to FitMart, whether you're contributing to open source for the first time or you're a seasoned developer.


📌 Table of Contents


🧭 Code of Conduct

By participating in this project, you agree to be respectful and constructive. We expect everyone to:

  • Use welcoming and inclusive language
  • Be respectful of different viewpoints and experiences
  • Gracefully accept constructive feedback
  • Focus on what's best for the community

Harassment or toxic behavior of any kind will not be tolerated.


💡 How Can I Contribute?

You don't need to write code to contribute! Here are all the ways you can help:

Type Examples
🐛 Bug Fix Fix broken functionality, handle edge cases
New Feature Add something new to the app
📖 Documentation Improve README, add JSDoc comments, fix typos
🎨 UI/UX Improve design, responsiveness, accessibility
🧪 Tests Add unit or integration tests
🔧 Refactor Clean up code without changing behavior
💬 Discussion Comment on issues, review PRs, share ideas

🚀 Getting Started (Step-by-Step)

For Beginners — Read This Carefully!

If this is your first time contributing to open source, follow every step below. Don't skip anything!


Step 1: Fork the Repository

Go to the FitMart GitHub page and click the Fork button (top right corner).

This creates your own copy of the project under your GitHub account.


Step 2: Clone Your Fork

git clone https://github.com/<your-username>/FitMart.git
cd FitMart

Replace <your-username> with your actual GitHub username.


Step 3: Add the Upstream Remote

This connects your local copy to the original FitMart repo so you can pull in future updates:

git remote add upstream https://github.com/parthbuilds-community/FitMart.git

Verify it worked:

git remote -v
# Should show both origin (your fork) and upstream (original)

Step 4: Set Up the Project Locally

Follow the Quick Start guide in README.md to get both the client and server running locally.

You will need accounts or API keys for the following services:

Service Required? Purpose
MongoDB Atlas (or local) ✅ Required Primary database
Firebase ✅ Required Authentication
Razorpay ⚠️ Optional Payment processing
Google Gemini API ⚠️ Optional AI chatbot
RapidAPI (ExerciseDB) ⚠️ Optional Exercise library
SMTP provider ⚠️ Optional Transactional emails

✅ Make sure the app runs on your machine before making any changes. Optional services fail gracefully — you don't need all of them to run the app locally.


Step 5: Keep Your Fork Updated

Before starting any new work, always sync with the latest changes from the original repo:

git checkout main
git fetch upstream
git merge upstream/main
git push origin main

🎯 Picking an Issue

Finding Issues to Work On

Browse the Issues tab and look for these labels:

Label Meaning
good first issue 🌱 Great for beginners — well-scoped and documented
help wanted Open for anyone to pick up
bug Something is broken
enhancement New feature or improvement
documentation Docs-related work

Before You Start

Always comment on the issue first! Say something like:

"Hey, I'd like to work on this! I'll have a PR ready by [rough timeline]."

This prevents two people from working on the same thing. The maintainer will assign it to you.

Good First Contributions

If you're not sure where to start, here are some concrete areas that always benefit from attention:

  • Replacing any hardcoded http://localhost:5000 API URLs with import.meta.env.VITE_API_URL
  • Improving responsiveness of existing pages on mobile viewports
  • Adding JSDoc comments to utility functions in client/src/utils/
  • Writing more thorough input validation on form components
  • Improving accessibility (ARIA labels, keyboard navigation)

Want to Work on Something Not Listed?

Open a new issue first and describe what you'd like to do. Wait for a maintainer to respond before starting large changes — this avoids wasted effort.


🌿 Branching Strategy

Never commit directly to main. Always work on a separate branch.

Branch Naming

Use this format: type/short-description

# Examples:
git checkout -b fix/cart-reservation-bug
git checkout -b feat/product-search
git checkout -b docs/improve-contributing-guide
git checkout -b refactor/api-url-standardize
git checkout -b feat/workout-sync
Prefix Use For
feat/ New features
fix/ Bug fixes
docs/ Documentation changes
refactor/ Code cleanup
test/ Adding/updating tests
chore/ Build scripts, config, etc.

🛠️ Making Your Changes

  1. Make sure you're on your feature branch:

    git checkout -b feat/your-feature-name
  2. Make your changes in small, logical steps.

  3. Test your changes locally — make sure everything still works.

  4. If you've added a new route to the server, verify it appears correctly in the API Reference section of the README, and update it if not.

  5. If you've added a new page or component, verify the Project Structure in the README accurately reflects it.

  6. Stage and commit your changes (see commit format below):

    git add .
    git commit -m "feat: add product search functionality"
  7. Push to your fork:

    git push origin feat/your-feature-name

📝 Commit Message Convention

We follow the Conventional Commits standard. This keeps the history clean and readable.

Format

type(scope): short description

[optional longer description]

[optional: closes #issue-number]

Examples

feat(cart): add quantity update button on cart page
fix(auth): resolve Google sign-in redirect loop
docs(readme): add environment variable instructions
refactor(client): replace hardcoded API URLs with VITE_API_URL
feat(exercises): add exercise browser with ExerciseDB integration
fix(chatbot): add Gemini fallback responses for API unavailability
chore: update dependencies

Types

Type When to Use
feat New feature
fix Bug fix
docs Documentation only
style Formatting (no logic change)
refactor Code restructure (no feature/fix)
test Adding or updating tests
chore Build, config, tooling changes

💡 Keep the subject line under 72 characters and in lowercase.


🔃 Submitting a Pull Request

Once your changes are pushed to your fork:

  1. Go to the original FitMart repo.
  2. You'll see a "Compare & pull request" banner — click it.
  3. Fill out the PR template completely (see below).
  4. Set the base branch to main.
  5. Click "Create Pull Request".

PR Title Format

Use the same convention as commits:

feat(product): add product filter by category
fix(payment): handle failed payment edge case
docs(contributing): update env variable table

PR Description Template

Please fill this out when opening a PR:

## 📋 What does this PR do?
A clear summary of the changes made.

## 🔗 Related Issue
Closes #<issue-number>

## 🧪 How was this tested?
Describe how you tested your changes (manual steps, screenshots, etc.)

## 📸 Screenshots (if UI changes)
Before / After screenshots if you changed any UI.

## ✅ Checklist
- [ ] I've read the CONTRIBUTING guide
- [ ] My code follows the project's style guidelines
- [ ] I've tested my changes locally
- [ ] I've included unit tests if adding/changing core backend logic
- [ ] I've linked the related issue
- [ ] I haven't introduced any new secrets or API keys
- [ ] I've updated README.md if I added a new route, page, component, or env variable

🔍 PR Review Process

After you open a PR:

  1. Automated checks may run (linting, etc.) — make sure they pass.
  2. The maintainer (Parth) will review your PR and may leave comments.
  3. If changes are requested:
    • Make the changes on the same branch
    • Push the new commits — the PR updates automatically
    • Reply to comments once addressed
  4. Once approved, your PR will be merged 🎉

⏱️ Be patient — reviews can take a few days. Feel free to ping if there's no response after a week.


📁 Project Structure Reference

FitMart/
├── client/                   # React + Vite Frontend
│   ├── src/
│   │   ├── components/       # Reusable UI components (uses Framer Motion for animations)
│   │   ├── auth/             # Firebase auth setup & hooks
│   │   ├── pages/            # Route-level page components
│   │   └── utils/            # Helper/utility functions
│   └── .env.local            # ⚠️ Not committed — create manually
│
├── server/                   # Node.js + Express Backend
│   ├── middleware/           # Express middleware (logger, auth verification)
│   ├── models/               # Mongoose schemas
│   ├── routes/               # Route handlers
│   ├── services/             # Business logic services (email, etc.)
│   ├── db.js                 # MongoDB connection
│   ├── firebaseAdmin.js      # Firebase Admin SDK setup
│   ├── index.js              # Server entry point (middleware, routes, error handler)
│   ├── seed.js               # Product DB seed script
│   └── seedFitnessCenters.js # Fitness center DB seed script
│
└── docs/
    ├── CONTRIBUTING.md                 # This file
    ├── FIRST_PURCHASE_EMAIL_SETUP.md   # Email feature setup guide
    └── SECURITY.md                     # Responsible disclosure policy

Key Conventions to Know

Adding a new backend route:

  1. Create your route file in server/routes/your-feature.js
  2. Register it in server/index.js with app.use('/api/your-feature', require('./routes/your-feature'))
  3. Create the corresponding Mongoose model in server/models/YourModel.js if needed
  4. Update the API Reference table in README.md

Adding a new frontend page:

  1. Create your component in client/src/pages/YourPage.jsx
  2. Import it in client/src/App.jsx and add the <Route> entry
  3. Update the Pages & Routes table in README.md
  4. If your page needs auth guarding, wrap it in <AdminRoute> or <NonAdminRoute>

Adding a new environment variable:

  1. Add it to server/.env or client/.env locally
  2. Document it in the Environment Variables section of README.md
  3. Add a .env.example entry if one exists for that directory

Adding a new service (email, third-party API, etc.):

  1. Create it in server/services/your-service.js
  2. Fail gracefully when env variables are missing — never crash the server
  3. Document the required env variables in README.md and docs/FIRST_PURCHASE_EMAIL_SETUP.md (or a new doc) if the setup is non-trivial

🎨 Style Guide

JavaScript / React

  • Use functional components with hooks (no class components)
  • Prefer const over let; avoid var
  • Use async/await over raw Promises where possible
  • Keep components small and single-purpose
  • Name component files with PascalCase (e.g., ProductCard.jsx)
  • Name utility files with camelCase (e.g., formatPrice.js)
  • Use the normalizeProduct utility from client/src/utils/normalizeProduct.js when working with product data from the API to safely handle both id and productId fields

CSS / Tailwind

  • Use Tailwind utility classes wherever possible
  • Stick to the stone-* color palette only — no blue, green, or purple (see the Design System in client/DesignSystem.md)
  • Keep custom CSS to a minimum
  • Ensure UI is responsive and works on mobile
  • Use rounded-full for buttons, rounded-2xl for cards, and rounded-lg for inputs
  • Always precede major section headings with the eyebrow label pattern: text-xs tracking-[0.2em] uppercase text-stone-400
  • Use DM Serif Display for headings and DM Sans for body/UI text

Backend (Node/Express)

  • Keep route files focused on a single resource
  • Put business logic and reusable logic in server/services/ — not directly in routes
  • Always validate input (required fields, types) and return clear error messages
  • Always handle errors with try/catch and return a clean JSON error response
  • Use the verifyFirebaseToken middleware from server/middleware/verifyFirebaseToken.js for any endpoint that requires a logged-in user
  • Never log or expose sensitive values (API keys, passwords) — the request logger already redacts password, token, secret, and apiKey keys
  • New services that depend on env variables must fail gracefully (log a warning, return null, and allow the rest of the app to function) — do not call process.exit()

Animations (Framer Motion)

  • Use Framer Motion for all UI animations — page transitions, modal entrances, hover effects
  • Keep animations quick (150-300ms) and subtle — no distracting or overly complex movements
  • Prefer motion components over CSS transitions for interactive elements
  • Use AnimatePresence for exit animations on unmounting components
  • Example pattern:
    import { motion, AnimatePresence } from 'framer-motion';
    
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      animate={{ opacity: 1, y: 0 }}
      exit={{ opacity: 0, y: -20 }}
      transition={{ duration: 0.2 }}
    >

General

  • No hardcoded URLs — use import.meta.env.VITE_API_URL on the client and environment variables on the server
  • No committed secrets.env files are gitignored for a reason
  • Delete commented-out code before submitting a PR
  • Write clear variable and function names — code should read like English
  • When touching UserProfile, remember it tracks email, firstPurchaseEmailSentAt, and lastReminderEmailSentAt for the email services — don't overwrite these fields unintentionally
  • Animations — Use Framer Motion for all animations and transitions (page entrances, modals, hover effects, etc.). Keep animations subtle and performant — avoid over-animating.

🆘 Need Help?

Stuck? Don't worry — everyone was a beginner once.

  • 💬 Comment on the issue you're working on with your question
  • 🐛 Open a new issue with the question label
  • 📖 Re-read the README — the setup steps cover most common problems
  • 🔐 For security issues, follow the responsible disclosure process in docs/SECURITY.md — do not open a public issue

🧪 Feature Setup Guides

Below are two developer-facing setup guides added here for convenience: local development admin authentication (useful for contributors testing admin pages) and the first-purchase email feature setup. These are summarized from dedicated docs in docs/ and include the most common setup steps and environment variables.

Local Development Admin (quick guide)

Purpose: let contributors run and test admin pages locally without using production Firebase admin credentials.

  • When to use: NODE_ENV=development on the server and client.
  • Server-side: a development-only endpoint POST /api/dev/login is registered only in development and returns a lightweight token of the form dev:<email> when the provided email matches DEV_ADMIN_EMAIL in the server .env.
  • Client-side: a dev login page is available at /dev-login (development only). It calls the server endpoint and stores the returned token in localStorage as dev_token.
  • Middleware behavior: verifyFirebaseToken recognizes dev: tokens when not in production and sets req.user. verifyAdmin allows the dev admin when DEV_ADMIN_EMAIL or DEV_ADMIN_UID matches.

Key environment variables (development)

  • Server: DEV_ADMIN_EMAIL (required), DEV_ADMIN_UID (optional), NODE_ENV=development, MONGO_URI.
  • Client: VITE_DEV_ADMIN_EMAIL (should match server setting), VITE_API_URL.

Quick start (local)

  1. Create server/.env from server/.env.example and set DEV_ADMIN_EMAIL and MONGO_URI.
  2. Create client/.env from client/.env.example and set VITE_DEV_ADMIN_EMAIL and VITE_API_URL.
  3. Start MongoDB.
  4. Run server and client:
cd server
npm install
npm run dev
cd ../client
npm install
npm run dev
  1. Open http://localhost:5173/dev-login, enter DEV_ADMIN_EMAIL, and submit. You will be redirected to /admin/dashboard with a local dev session.

Security notes

  • Dev tokens are local-only and NOT signed — they are for development and testing only.
  • Dev endpoints and token acceptance are disabled in production (NODE_ENV=production).
  • Never commit .env files with secrets.

Files referenced (added/modified)

  • server/routes/devAuth.js (new) — development-only login endpoint
  • server/middleware/verifyFirebaseToken.js (modified) — accepts dev: tokens in development
  • server/middleware/verifyAdmin.js (modified) — allows DEV_ADMIN_EMAIL/DEV_ADMIN_UID in development
  • client/src/components/DevAdminLogin.jsx (new) — dev login UI
  • client/src/utils/getAuthHeaders.js (modified) — reads dev_token from localStorage in development

For the full contributor guide and more details, see docs/LOCAL_DEV_ADMIN_README.md.

First-purchase Email Feature (quick guide)

Purpose: send a welcome email to users after their first paid order. This guide summarizes setup, testing, and operational notes.

Overview

  • The server contains a modular email pipeline: emailService (Nodemailer), emailTemplates, and firstPurchaseEmailService which is called after an order is marked paid.
  • Email sending is asynchronous and fails gracefully (does not block the payment flow).

Required environment variables

  • SMTP_HOST, SMTP_PORT, SMTP_SECURE (true/false), SMTP_USER, SMTP_PASS, SMTP_FROM, APP_BASE_URL (client URL used in email CTAs).

Quick start & testing

  1. Add SMTP vars to server/.env (see above). For Gmail use an App Password.
  2. Start server and client (see steps in Local Development Admin quick start).
  3. Run a demo payment flow or call the demo endpoint to simulate a paid order:
POST http://localhost:5000/api/payment/demo-success
Content-Type: application/json

{ "userId": "test-user-id-123" }
  1. Verify server logs for email send confirmation and that UserProfile.firstPurchaseEmailSentAt was set.

Testing scenarios to consider

  • First purchase success (email should be sent once).
  • Duplicate prevention (subsequent purchases should not re-send the email).
  • Missing SMTP config (email sending should be skipped and app should not crash).

Files referenced (added/modified)

  • server/services/emailService.js (NEW) — Nodemailer wrapper and transporter management
  • server/services/emailTemplates.js (NEW) — HTML/text templates generator
  • server/services/firstPurchaseEmailService.js (NEW) — business logic to decide & send emails
  • server/models/UserProfile.js (modified) — email and firstPurchaseEmailSentAt fields
  • server/routes/payment.js (modified) — triggers email sending on payment verification and demo-success

For the complete detailed guide, troubleshooting tips, and production recommendations, see docs/FIRST_PURCHASE_EMAIL_SETUP.md.

There are no dumb questions. Ask away! 🙌


Happy coding! We're glad you're here. 🚀

Made with ❤️ by Parth Narkar and the Parth Builds Community