Skip to content

Elham-EN/tikdo-backend

Repository files navigation

Tikdo Backend

Table of Contents


API Documentation

Interactive API docs powered by Swagger UI.

Access: http://localhost:3000/docs

Documentation Structure

The OpenAPI documentation is organized in a modular structure:

src/docs/
├── openapi.ts              # Main file (merges all paths)
├── schemas/                # Reusable schemas
│   ├── common.schema.ts    # Common responses (errors, etc.)
│   └── task.schema.ts      # Task-related schemas
└── paths/                  # Endpoint definitions
    ├── data.paths.ts       # /api/v1/data endpoints
    └── tasks.paths.ts      # /api/v1/tasks endpoints

Adding New Endpoints

Step 1: Define schemas (if needed)

Create or update schema files in src/docs/schemas/:

// src/docs/schemas/user.schema.ts
import type { OpenAPIV3 } from 'openapi-types';

export const userSchema: OpenAPIV3.SchemaObject = {
  type: 'object',
  properties: {
    id: { type: 'integer', example: 1 },
    name: { type: 'string', example: 'John Doe' },
    email: { type: 'string', example: 'john@example.com' }
  }
};

export const createUserSchema: OpenAPIV3.SchemaObject = {
  type: 'object',
  required: ['name', 'email'],
  properties: {
    name: { type: 'string', example: 'John Doe' },
    email: { type: 'string', example: 'john@example.com' }
  }
};

Step 2: Create path definitions

Create a new file in src/docs/paths/:

// src/docs/paths/users.paths.ts
import type { OpenAPIV3 } from 'openapi-types';
import { userSchema, createUserSchema } from '../schemas/user.schema.js';
import { commonResponses } from '../schemas/common.schema.js';

export const usersPaths: OpenAPIV3.PathsObject = {
  '/api/v1/users': {
    get: {
      summary: 'List all users',
      tags: ['Users'],
      responses: {
        '200': {
          description: 'Success',
          content: {
            'application/json': {
              schema: {
                type: 'array',
                items: userSchema
              }
            }
          }
        },
        '500': commonResponses[500]
      }
    },
    post: {
      summary: 'Create a new user',
      tags: ['Users'],
      requestBody: {
        required: true,
        content: {
          'application/json': {
            schema: createUserSchema
          }
        }
      },
      responses: {
        '201': {
          description: 'User created',
          content: {
            'application/json': {
              schema: userSchema
            }
          }
        },
        '400': commonResponses[400],
        '500': commonResponses[500]
      }
    }
  }
};

Step 3: Import and merge paths

Update src/docs/openapi.ts:

import { usersPaths } from './paths/users.paths.js';

export const openApiSpec: OpenAPIV3.Document = {
  // ... existing config
  paths: {
    ...dataPaths,
    ...tasksPaths,
    ...usersPaths  // Add your new paths
  }
};

Step 4: View updated docs

Start the server and visit http://localhost:3000/docs to see your new endpoints.

Benefits

  • Organized: Each resource in its own file
  • Reusable: Define schemas once, use everywhere
  • Scalable: Easy to add endpoints without cluttering
  • Type-safe: Full TypeScript support

Code Quality

ESLint & Prettier

Tool Purpose
ESLint Catches bugs, enforces best practices, prevents bad patterns
Prettier Auto-formats code for consistent style

Commands

# Check for issues
npm run lint

# Auto-fix issues
npm run lint:fix

# Format code
npm run format

# Check formatting without changes
npm run format:check

When to Use

  • Before committing: Run npm run lint:fix && npm run format
  • During development: IDE extensions auto-fix on save
  • In CI/CD: Run npm run lint && npm run format:check to block bad code

IDE Setup (VSCode)

Install extensions:

Add to .vscode/settings.json:

{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": "explicit"
  }
}

Testing

Overview

Testing is powered by Jest with TypeScript support via ts-jest. Tests follow the Arrange, Act, Assert (AAA) pattern.

Test Type Location Purpose
Unit tests/unit/ Test individual functions/modules in isolation
Integration tests/integration/ Test multiple components working together

Commands

# Run all tests
npm test

# Run tests in watch mode (re-runs on file changes)
npm run test:watch

# Run tests with coverage report
npm run test:coverage

# Run only unit tests
npm run test:unit

# Run only integration tests
npm run test:integration

File Structure

Mirror the src/ structure inside tests/:

tests/
├── unit/
│   └── shared/utils/
│       └── dateHelper.test.ts    # Tests for src/shared/utils/dateHelper.ts
└── integration/
    └── *.test.ts

When to Write Tests

Focus on tests that have high impact on behavior. Don't write tests for everything — write them where they matter.

Write unit tests when you add:

Scenario Example
Input validation logic Validating task title is not empty, date format, etc.
Data transformation Converting dates, formatting responses, mapping data
Business rules Overdue detection, task status transitions
Utility functions Helpers with logic that could break

Write integration tests when you add:

Scenario Example
API endpoints POST /tasks returns 201 with valid data, 400 without
Database operations Task CRUD operations persist and retrieve correctly
Multi-step workflows Creating a task then moving it between lists

Skip tests for:

  • Config/setup files (prisma.ts, server.ts)
  • Static definitions (OpenAPI schemas, types)
  • Simple pass-through code with no logic

Writing Tests

Create test files with .test.ts extension using the AAA pattern:

import { describe, it, expect } from '@jest/globals';

describe('validateTaskInput', () => {
  // Test Case: valid input
  it('should accept a task with a title', () => {
    // Arrange
    const input = { title: 'Buy groceries' };

    // Act
    const result = validateTaskInput(input);

    // Assert
    expect(result.isValid).toBe(true);
  });

  // Test Case: invalid input
  it('should reject a task without a title', () => {
    // Arrange
    const input = { title: '' };

    // Act
    const result = validateTaskInput(input);

    // Assert
    expect(result.isValid).toBe(false);
    expect(result.error).toBe('Title is required');
  });
});

Coverage

After running npm run test:coverage, view the report:

  • Terminal: Summary displayed after tests
  • HTML: Open coverage/index.html in browser
  • CI/CD: Use coverage/lcov.info for coverage tools

CI/CD (GitHub Actions)

Overview

Automated checks run on every push and pull request to main and develop branches.

What Gets Checked

Step What it does
Lint Runs ESLint to catch code issues
Format Checks Prettier formatting
Type check Validates TypeScript types
Test Runs all Jest tests

Setup Instructions

  1. File location: .github/workflows/ci.yml (already created)

  2. Push to GitHub:

    git add .github/workflows/ci.yml
    git commit -m "chore(ci): add GitHub Actions workflow"
    git push
  3. View results: Go to your GitHub repo → Actions tab

  4. (Optional) Enable branch protection:

    • Go to repo SettingsBranches
    • Click Add rule for main
    • Enable Require status checks to pass before merging
    • Select build-and-test from the list

Status Badge

Add to the top of your README:

![CI](https://github.com/YOUR_USERNAME/YOUR_REPO/actions/workflows/ci.yml/badge.svg)

Conventional Commits

Format: type(scope): description

Type When to Use
feat New feature
fix Bug fix
docs Documentation only
style Formatting, no code change
refactor Code restructure, no behavior change
test Adding/updating tests
chore Build, config, dependencies

Examples

feat(auth): add login endpoint
fix(api): handle null response
docs(readme): update setup instructions
refactor(users): extract validation logic
chore(deps): upgrade express to v5

Rules

  • Use lowercase
  • No period at end
  • Keep under 72 characters
  • Use imperative mood ("add" not "added")

Git Branches

Branch Naming

Format: type/short-description

Prefix Purpose
main Production-ready code
develop Integration branch
feature/ New features
fix/ Bug fixes
hotfix/ Urgent production fixes
release/ Release preparation

Examples

feature/user-authentication
feature/add-payment-api
fix/login-validation-error
hotfix/security-patch
release/v1.2.0

Workflow

# Create feature branch
git checkout -b feature/add-login develop

# Work on feature...
git add .
git commit -m "feat(auth): add login endpoint"

# Push and create PR
git push -u origin feature/add-login

# Go back to main branch
git checkout main

# Get update remote repo
git pull

# After PR merged, delete branch
git branch -d feature/add-login

Rules

  • Branch from develop for features/fixes
  • Branch from main for hotfixes
  • Keep branch names short and descriptive
  • Delete branches after merging

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors