Skip to content

Contributors Guide

This guide explains how to work on Unwrap: the conventions, the PR process, and the standards your changes will be evaluated against.

NOTE

These guidelines are set to change and must be updated once agreed upon with team and other relevant stakeholders. If you haven't run the project yet, start with Get Started.

Project context

Unwrap is a group student project submitted for assessment. The frontend is owned and maintained separately from the backend.

Frontend scope includes:

  • Everything under src/
  • All test infrastructure (src/__tests__/, src/test/, src/mocks/)
  • CI configuration (.github/workflows/)
  • All documentation (docs/, README.md)

Branching

The project uses trunk-based development with short-lived feature branches. The main branch is protected and no direct pushes are allowed. Every change goes through a pull request.

Branch naming

<type>/<short-description>

Where <type> is one of:

PrefixUse for
feat/New user-facing or developer-facing functionality
fix/Bug fixes
chore/Tooling, dependencies, config, non-code maintenance
docs/Documentation only
test/Adding or improving tests
refactor/Internal restructuring without behaviour change

Examples: feat/top-albums-card, fix/upload-zip-validation, docs/architecture-page.

Branch lifetime

Keep branches short-lived, ideally less than a few days. Long-lived branches accumulate merge conflicts and review burden. If a feature is large, split it into multiple PRs.

Commits

Commits are based on the Conventional Commits spec.

<type>(<scope>): <subject>
ElementNotes
typeSame set as branch prefixes: feat, fix, chore, docs, test, refactor
scopeOptional. The area of the codebase, e.g. dashboard, upload, ci
subjectImperative present tense, lowercase. No trailing period.

Good:

feat(dashboard): add Top Albums stat card

Bad:

update stuff

Commits should be atomic

One logical change per commit. If you can describe two things your commit does using "and", split it.

The PR process

1. Open the PR

Push your branch and open a pull request against main. Include:

  • A clear title following commit conventions above
  • Add an optional body that says: what changed, why, and any context a reviewer needs

2. CI runs automatically

Every PR triggers GitHub Actions, which run on a Node 24 environment:

JobWhat it checks
unit (+integration) testsnpm run test:run (full Vitest suite)
e2e-testsnpx playwright test

CI must pass before the PR can be merged. If a job fails, fix the issue locally and push again.

3. Review

Self-review your own PR first: read the diff as if you were reviewing someone else's change. Catch obvious issues before a human does.

For larger changes or anything architectural, request a review where possible. Address feedback in new commits. Don't force-push during review.

4. Merge

PRs are merged into main via Merge pull request. Merge commits go onto main.

After merge, the feature branch is deleted automatically.

Code conventions

File and folder layout

  • Components: src/components/<Name>/<Name>.tsx + <Name>.module.css
  • Pages: src/pages/<Name>.tsx (routes are top-level)
  • Tests: mirror the source path under src/__tests__/

TypeScript

  • any is forbidden by ESLint. Use unknown and narrow, or define an interface.
  • API response shapes live in src/types/api.ts — keep them aligned with the backend.
  • Prefer interfaces over type aliases for object shapes.

React

  • Default exports for components. One component per file.
  • Hooks go in src/hooks/ and start with use.
  • No inline fetch calls. All data fetching goes through a service → hook.

CSS

  • CSS Modules only. Import as import styles from './X.module.css'.
  • Use the design token CSS variables (--color-surface, --radius, etc.) — don't hardcode colours.
  • Component-scoped class names; no global styles outside src/index.css.

Testing standards

  • Every new component should have at least one integration test.
  • Every new service or util should have unit tests.
  • Tests should describe behaviour, not implementation. it('shows an error when the request fails'), not it('renders the .error className').
  • Use the shared renderWithProviders and server from src/test/. Don't roll your own setup.

For patterns, see How to write a test.

Pre-commit hooks

Husky runs lint-staged on every commit:

  • ESLint with auto-fix on staged .ts, .tsx files
  • Prettier on staged .ts, .tsx, .css, .md files

If a hook fails, the commit is rejected. Fix the reported issues and commit again. Don't bypass with --no-verify unless you have a clear reason because CI will catch the same issues anyway.

What "ready for review" means

Before requesting review, your PR should:

  • ✅ Pass CI (all green)
  • ✅ Have no console.log or commented-out code
  • ✅ Have tests for new behaviour
  • ✅ Update docs if you changed something documented

Questions

If something here is unclear or contradicts what you see in the code, that's a documentation bug, open an issue or a docs PR.

Built for SE_07 — Technical Documentation