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.
- Code of Conduct
- How Can I Contribute?
- Getting Started (Step-by-Step)
- Picking an Issue
- Branching Strategy
- Making Your Changes
- Commit Message Convention
- Submitting a Pull Request
- PR Review Process
- Project Structure Reference
- Style Guide
- Need Help?
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.
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 |
If this is your first time contributing to open source, follow every step below. Don't skip anything!
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.
git clone https://github.com/<your-username>/FitMart.git
cd FitMartReplace
<your-username>with your actual GitHub username.
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.gitVerify it worked:
git remote -v
# Should show both origin (your fork) and upstream (original)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 | Payment processing | |
| Google Gemini API | AI chatbot | |
| RapidAPI (ExerciseDB) | Exercise library | |
| SMTP provider | 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.
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 mainBrowse 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 |
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.
If you're not sure where to start, here are some concrete areas that always benefit from attention:
- Replacing any hardcoded
http://localhost:5000API URLs withimport.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)
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.
Never commit directly to main. Always work on a separate branch.
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. |
-
Make sure you're on your feature branch:
git checkout -b feat/your-feature-name
-
Make your changes in small, logical steps.
-
Test your changes locally — make sure everything still works.
-
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.
-
If you've added a new page or component, verify the Project Structure in the README accurately reflects it.
-
Stage and commit your changes (see commit format below):
git add . git commit -m "feat: add product search functionality"
-
Push to your fork:
git push origin feat/your-feature-name
We follow the Conventional Commits standard. This keeps the history clean and readable.
type(scope): short description
[optional longer description]
[optional: closes #issue-number]
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| 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.
Once your changes are pushed to your fork:
- Go to the original FitMart repo.
- You'll see a "Compare & pull request" banner — click it.
- Fill out the PR template completely (see below).
- Set the base branch to
main. - Click "Create Pull Request".
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
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 variableAfter you open a PR:
- Automated checks may run (linting, etc.) — make sure they pass.
- The maintainer (Parth) will review your PR and may leave comments.
- If changes are requested:
- Make the changes on the same branch
- Push the new commits — the PR updates automatically
- Reply to comments once addressed
- 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.
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
Adding a new backend route:
- Create your route file in
server/routes/your-feature.js - Register it in
server/index.jswithapp.use('/api/your-feature', require('./routes/your-feature')) - Create the corresponding Mongoose model in
server/models/YourModel.jsif needed - Update the API Reference table in
README.md
Adding a new frontend page:
- Create your component in
client/src/pages/YourPage.jsx - Import it in
client/src/App.jsxand add the<Route>entry - Update the Pages & Routes table in
README.md - If your page needs auth guarding, wrap it in
<AdminRoute>or<NonAdminRoute>
Adding a new environment variable:
- Add it to
server/.envorclient/.envlocally - Document it in the Environment Variables section of
README.md - Add a
.env.exampleentry if one exists for that directory
Adding a new service (email, third-party API, etc.):
- Create it in
server/services/your-service.js - Fail gracefully when env variables are missing — never crash the server
- Document the required env variables in
README.mdanddocs/FIRST_PURCHASE_EMAIL_SETUP.md(or a new doc) if the setup is non-trivial
- Use functional components with hooks (no class components)
- Prefer
constoverlet; avoidvar - 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
normalizeProductutility fromclient/src/utils/normalizeProduct.jswhen working with product data from the API to safely handle bothidandproductIdfields
- Use Tailwind utility classes wherever possible
- Stick to the
stone-*color palette only — no blue, green, or purple (see the Design System inclient/DesignSystem.md) - Keep custom CSS to a minimum
- Ensure UI is responsive and works on mobile
- Use
rounded-fullfor buttons,rounded-2xlfor cards, androunded-lgfor inputs - Always precede major section headings with the eyebrow label pattern:
text-xs tracking-[0.2em] uppercase text-stone-400 - Use
DM Serif Displayfor headings andDM Sansfor body/UI text
- 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
verifyFirebaseTokenmiddleware fromserver/middleware/verifyFirebaseToken.jsfor 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, andapiKeykeys - 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()
- 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
motioncomponents over CSS transitions for interactive elements - Use
AnimatePresencefor 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 }} >
- No hardcoded URLs — use
import.meta.env.VITE_API_URLon the client and environment variables on the server - No committed secrets —
.envfiles 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 tracksemail,firstPurchaseEmailSentAt, andlastReminderEmailSentAtfor 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.
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
questionlabel - 📖 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
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.
Purpose: let contributors run and test admin pages locally without using production Firebase admin credentials.
- When to use:
NODE_ENV=developmenton the server and client. - Server-side: a development-only endpoint
POST /api/dev/loginis registered only in development and returns a lightweight token of the formdev:<email>when the provided email matchesDEV_ADMIN_EMAILin 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 inlocalStorageasdev_token. - Middleware behavior:
verifyFirebaseTokenrecognizesdev:tokens when not in production and setsreq.user.verifyAdminallows the dev admin whenDEV_ADMIN_EMAILorDEV_ADMIN_UIDmatches.
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)
- Create
server/.envfromserver/.env.exampleand setDEV_ADMIN_EMAILandMONGO_URI. - Create
client/.envfromclient/.env.exampleand setVITE_DEV_ADMIN_EMAILandVITE_API_URL. - Start MongoDB.
- Run server and client:
cd server
npm install
npm run dev
cd ../client
npm install
npm run dev- Open
http://localhost:5173/dev-login, enterDEV_ADMIN_EMAIL, and submit. You will be redirected to/admin/dashboardwith 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
.envfiles with secrets.
Files referenced (added/modified)
server/routes/devAuth.js(new) — development-only login endpointserver/middleware/verifyFirebaseToken.js(modified) — acceptsdev:tokens in developmentserver/middleware/verifyAdmin.js(modified) — allowsDEV_ADMIN_EMAIL/DEV_ADMIN_UIDin developmentclient/src/components/DevAdminLogin.jsx(new) — dev login UIclient/src/utils/getAuthHeaders.js(modified) — readsdev_tokenfromlocalStoragein development
For the full contributor guide and more details, see docs/LOCAL_DEV_ADMIN_README.md.
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, andfirstPurchaseEmailServicewhich 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
- Add SMTP vars to
server/.env(see above). For Gmail use an App Password. - Start server and client (see steps in Local Development Admin quick start).
- 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" }- Verify server logs for email send confirmation and that
UserProfile.firstPurchaseEmailSentAtwas 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 managementserver/services/emailTemplates.js(NEW) — HTML/text templates generatorserver/services/firstPurchaseEmailService.js(NEW) — business logic to decide & send emailsserver/models/UserProfile.js(modified) —emailandfirstPurchaseEmailSentAtfieldsserver/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