DEV Community

M TECHUB LLc
M TECHUB LLc

Posted on

Setting Up a Fitness App Project: Repository Structure, CI, and Documentation


The first workout screen works. Users can record a session, and the API saves it.

Then another developer joins. They cannot identify the required environment variables. The backend starts only after an undocumented database change. A pull request breaks a calculation, but nobody notices until someone tests the screen manually.

The project needs a repeatable way to understand, verify, and change its behavior.

A maintainable fitness app project setup connects clear component boundaries, automated checks, and documentation another developer can follow.

This guide uses a hypothetical fitness application, not a real production system. It contains a mobile client and a Node.js API, with an optional administration interface.

Define the Architecture Before Creating Folders

Identify what runs, what stores data, and what communicates across a boundary.

For the hypothetical application:

  • The mobile client presents workouts and records input.
  • The backend API authenticates requests and manages application data.
  • The database stores users, exercises, and workout records.
  • An optional administration interface manages approved content.
  • Shared schemas describe selected request and response formats.
  • Tests and development tools verify the components.

A database layer can remain part of the API. A shared package should exist because multiple components need a maintained contract, not simply because monorepos often contain one.

Monorepo or Separate Repositories?

A monorepo keeps related components together and can make coordinated API, schema, and client changes easier to review.

Separate repositories can suit independent ownership, access restrictions, or release processes.

Consideration Monorepo Separate repositories
Coordinated changes One pull request can cover related changes Changes need cross-repository coordination
Access boundaries Usually broader repository visibility Access can be isolated by component
Shared tooling Central configuration is possible Configuration may need distribution
Releases Require component-specific conventions Separate releases still need compatibility planning

Choose according to actual coordination and ownership needs.

For framework planning, see React Native vs Flutter for fitness app development. Document the approach actually selected and its platform-specific requirements.

Design a Practical Repository Structure

This directory map is illustrative, not a mandatory template.

Path Responsibility
apps/mobile/ Mobile application
apps/admin/ Optional administration interface
services/api/ Backend and data-access layer
services/api/src/ API implementation
services/api/tests/ API unit and integration tests
services/api/migrations/ Database migrations when required
packages/shared/ Shared contracts when justified
docs/ Architecture, setup, API, and deployment documentation
scripts/ Maintained development utilities
tests/e2e/ Cross-component user-journey tests
.github/workflows/ GitHub Actions workflows
.github/PULL_REQUEST_TEMPLATE.md Pull request prompts
.gitignore Excluded local and generated files
.editorconfig Basic editor conventions
README.md Project entry point
CONTRIBUTING.md Collaboration instructions

The API in this example has its own package manifest and lockfile. The repository does not use npm workspaces.

A smaller project can omit the admin application, shared package, and cross-component test directory.

Choose license terms appropriate to the project's intended distribution. Do not automatically apply an open-source license to proprietary code.

Organize Code Around Responsibilities

For workout logging, separate presentation, application logic, business rules, data access, and authorization.

A screen should not independently implement access policy. The backend must enforce access to protected data.

Workout calculations should not depend on UI components. A duration function should receive defined inputs and return a result without requiring a network connection.

This makes empty records, invalid values, and unit conventions easier to test.

Avoid creating interfaces and factories for every small function. Introduce abstraction when it manages an existing dependency or variation.

For related domain planning, see fitness tracking app development.

Establish Git and Collaboration Conventions

Short-lived branches and pull requests may provide enough structure for a small team.

Document branch creation, review responsibilities, required checks, release identification, and urgent-fix procedures.

Commit messages should describe the change:

Add workout history filtering by date
Reject negative exercise duration values
Fix duplicate workout import after retry
Document local database migration setup
Enter fullscreen mode Exit fullscreen mode

If using Conventional Commits, document the rules and any tooling that depends on them.

Make Pull Requests Easier to Review

A useful description answers:

  1. What behavior changed?
  2. Why was it needed?
  3. How was it verified?
  4. Does it require a migration or configuration change?
  5. Which documentation changed?

Configure appropriate branch protection or rulesets where available. Record exact required check names: renaming a workflow check can affect merging.

Commit applicable lockfiles and review dependency changes with the application changes.

Configure Continuous Integration Around Real Checks

Continuous integration runs verification when changes are proposed or integrated.

Suitable checks include dependency installation, formatting, linting, type checking, unit tests, integration tests, builds, and security checks.

Each check should answer a question. A build verifies compilation; it does not prove that a workout is saved correctly.

CI differs from deployment. Successful checks do not require publishing an app or changing production.

Start with a small pipeline that reliably runs meaningful checks. Extend it when additional risks justify the work.

A Minimal GitHub Actions Workflow

This workflow checks only the hypothetical Node.js API.

Assumptions:

  • The API lives in services/api/.
  • It has its own committed package-lock.json.
  • It does not depend on an unconfigured local shared package.
  • Node.js 24 is compatible with its dependencies.
  • The package defines lint, test, and build scripts.
  • Tests run once and exit.
  • Production credentials are unnecessary.

Node.js 24 is a supported LTS line at the time of writing. Choose a supported version compatible with your project and align local development with CI.

Reference: Node.js release information.

Create .github/workflows/ci.yml:

name: API CI

on:
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  api-checks:
    name: API checks
    runs-on: ubuntu-latest
    timeout-minutes: 15

    defaults:
      run:
        working-directory: services/api

    steps:
      - name: Check out repository
        uses: actions/checkout@v7
        with:
          persist-credentials: false

      - name: Set up Node.js
        uses: actions/setup-node@v7
        with:
          node-version: "24"
          package-manager-cache: false

      - name: Install dependencies
        run: npm ci

      - name: Run lint checks
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Validate build
        run: npm run build
Enter fullscreen mode Exit fullscreen mode

The workflow uses read-only repository permissions and disables persisted checkout credentials. It has no deployment step.

Consult the official checkout and setup-node documentation for runner compatibility.

For stronger control over updates, use reviewed full commit SHA pins and maintain an update process.

Configure the Package Scripts First

For a TypeScript API using ESLint and Vitest, the relevant package manifest excerpt could be:

{
  "private": true,
  "scripts": {
    "lint": "eslint .",
    "test": "vitest run",
    "build": "tsc -p tsconfig.json"
  }
}
Enter fullscreen mode Exit fullscreen mode

This is not a complete manifest. It requires installed development dependencies, ESLint configuration, TypeScript configuration, and actual tests.

Do not hide missing required scripts with optional execution flags.

The npm ci command requires an existing lockfile and fails if it does not match the manifest. Keep installation settings consistent with those used to create the lockfile.

Reference: npm ci documentation.

Add Mobile Validation Separately

Passing API checks does not verify the mobile application.

Add checks appropriate to the actual framework and supported platforms. iOS build jobs generally need suitable macOS infrastructure and the relevant Apple toolchain.

Keep signed releases separate from ordinary pull request checks.

Handle Environment Configuration Safely

Document configuration separately for each component and environment.

An API example configuration file could contain:

DATABASE_URL=
AUTH_ISSUER_URL=
PORT=3000
Enter fullscreen mode Exit fullscreen mode

The mobile component might use:

API_BASE_URL=http://localhost:3000
Enter fullscreen mode Exit fullscreen mode

These examples contain no credentials. Explain how configuration is loaded and validated; an example file does not implement environment loading.

For emulators and physical devices, document how to reach the development API. Localhost refers to the device or machine interpreting the address.

Exclude Secrets and Generated Files

An illustrative root ignore file could include:

**/node_modules/
**/dist/
**/coverage/

.env
.env.*
**/.env
**/.env.*
!.env.example
!**/.env.example
Enter fullscreen mode Exit fullscreen mode

Adapt generated-file exclusions to the framework.

Ignore rules do not remove files already tracked or erase history. If a credential is exposed, rotate or revoke it, review its use, and then address repository exposure.

Use restricted CI secrets only when necessary. Ordinary checks should use isolated test resources.

Mobile application configuration is not a safe place for privileged server credentials.

Write Documentation Developers Can Use

Documentation should enable tasks without duplicating information reliably maintained by tooling.

Document Purpose
README.md Purpose, components, prerequisites, quick start, and checks
docs/architecture.md Boundaries, data flows, and design decisions
docs/development-setup.md Configuration, database setup, migrations, and synthetic data
docs/api-overview.md Authentication, errors, and maintained API contracts
docs/deployment.md Releases, migrations, monitoring, rollback, and recovery
CONTRIBUTING.md Branches, reviews, dependencies, and documentation expectations

A README outline:

# Project Name

## Purpose
## Components
## Prerequisites
## Local Setup
## Configuration
## Database Setup
## Running the Application
## Running Checks
## Troubleshooting
## Contribution Workflow
## Deployment Documentation
Enter fullscreen mode Exit fullscreen mode

Add verified commands and state where they run. Link to maintained API schemas rather than duplicating endpoint lists.

Update documentation in the same pull request as the relevant change.

For agency-built projects, also document repository administration and handover responsibilities. Related reading: fitness app development contracts: code and data ownership.

Document Fitness Data and Failure Behavior

Define identifiers, ownership, exercises, sets, repetitions, weights, units, duration, timestamps, completion, edits, and offline behavior.

Explain which records contribute to progress calculations. Record why each data field is collected and who can access it.

Related reading: fitness app data collection checklist.

Treat Integrations as Optional Components

Not every app needs HealthKit, Health Connect, or wearables.

When included, document permissions, supported data types, synchronization direction, provider limits, and disconnection.

Explain duplicate prevention, retries, missing information, expired authorization, delayed records, and partial imports.

Health Connect recommends aggregation for cumulative records such as steps to reduce double counting. Verify behavior for each record type and provider.

Reference: Health Connect data reading guidance.

Related reading:

Document Recommendation Logic If Present

Record inputs, constraints, model or provider versions, evaluation procedures, and fallbacks.

Rules and learned recommendations have different maintenance needs. Related reading: rules-based vs machine learning personalization.

Only include AI infrastructure when the product needs it.

Build Tests Around Important Decisions

Level Fitness-app example
Unit Validate duration calculations and invalid inputs
Integration Save and retrieve a workout through the API and database
End-to-end Sign in, complete a workout, and reopen its history
Build Compile supported application components
Regression Reproduce a previously fixed duplicate-import defect

Integration tests should use an isolated database with expected migrations. Never point them at production.

Use synthetic data and deterministic inputs. Test denied access as well as valid access, including whether one user can read another user's private workouts.

More expensive suites can run at appropriate stages, provided release-critical validation happens before release.

Plan Dependency and Access Maintenance

Record supported runtimes and check compatibility before upgrading.

Review dependency updates for purpose, maintenance, licensing, and operational implications.

Apply least privilege to repository members and CI identities. Restrict production records and release credentials.

Document upgrades, migration recovery, and incident responsibilities.

Automated vulnerability checks do not establish complete security or legal compliance. Privacy obligations depend on the product, data, jurisdictions, and agreements.

For related planning considerations, see fitness app HIPAA compliance and GDPR.

Common Setup Mistakes

Mistake Prevention
Unstructured code Define component responsibilities
Premature repositories and abstractions Add boundaries when justified
Missing lockfiles Commit and review applicable lockfiles
Unusable README Verify a clean setup
CI invokes nonexistent scripts Run every command locally first
Secrets are committed Use restricted configuration and review changes
Builds are treated as correctness proof Test behavior and integrations
Migrations are ignored Version them and test a fresh database
Only successful integrations are documented Explain retries, missing data, and denied access
Passing CI deploys production without controls Separate verification and release operations

Project Setup Checklist

Repository and Architecture

  • [ ] Identify components and ownership.
  • [ ] Choose repository boundaries based on actual needs.
  • [ ] Document important data flows.
  • [ ] Remove unnecessary abstractions.

Git and Collaboration

  • [ ] Define branches, reviews, and release conventions.
  • [ ] Add a useful pull request template.
  • [ ] Configure appropriate required checks.
  • [ ] Document urgent-fix procedures.

Dependencies and Environment

  • [ ] Record supported runtimes and toolchains.
  • [ ] Commit manifests and lockfiles.
  • [ ] Provide safe configuration examples.
  • [ ] Document database setup and migrations.

CI and Testing

  • [ ] Verify every CI script.
  • [ ] Run checks on pull requests and main-branch pushes.
  • [ ] Test business logic and integrations.
  • [ ] Validate supported mobile platforms.
  • [ ] Isolate tests from production.

Documentation

  • [ ] Add a verified quick start.
  • [ ] Explain architecture, APIs, and configuration.
  • [ ] Document common setup failures.
  • [ ] Update documentation with relevant changes.

Security and Access

  • [ ] Exclude secrets and generated files.
  • [ ] Review tracked files for sensitive information.
  • [ ] Apply least-privilege repository and CI permissions.
  • [ ] Define credential rotation and vulnerability handling.

Fitness Integrations

  • [ ] Document units and record identity.
  • [ ] Record applicable permissions and consent.
  • [ ] Test duplicate records and synchronization failures.
  • [ ] Explain external dependencies and fallbacks.

Deployment and Maintenance

  • [ ] Separate CI from releases.
  • [ ] Document deployment and migration procedures.
  • [ ] Define monitoring, rollback, and recovery.
  • [ ] Assign maintenance responsibilities.

Verify the Foundation With a Fresh Setup

Repository structure makes responsibilities visible. CI verifies selected behavior. Documentation explains how to work with the system.

Keep all three aligned with current requirements.

Ask another developer to clone the repository, follow the instructions, run the checks, and explain the main components. Fix the points where that process breaks.

Top comments (0)