Skip to content

Commit

Permalink
Configure Backend App (#1)
Browse files Browse the repository at this point in the history
* feat(structure): restructure api

* chore(update): update dependencies

* feat: add security middleware

* feat: add generic error handler

* feat(db): configure mongoose

* chore(style|ci): configure linter

* refactor(structure): reorg for coherence

* docs(readme): document project setup and architecture
  • Loading branch information
Connor-Bernard authored Nov 18, 2024
1 parent d39a44e commit e144eed
Show file tree
Hide file tree
Showing 28 changed files with 2,325 additions and 668 deletions.
30 changes: 0 additions & 30 deletions backend/.eslintrc.cjs

This file was deleted.

104 changes: 104 additions & 0 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Checkpoint Website Backend

Backend API service for the Checkpoint Website.

## Prerequisites

> [!TIP]
> You can use [nvm](https://github.com/nvm-sh/nvm) to install and manage Node.js versions. Once installed, you can use the command `nvm use` to automatically switch to the recommended engine version.
- Node.js (v18 or higher recommended)
- MongoDB (v6.0 or higher) (recommended, see the [MongoDB Installation Guide](https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-os-x/))

## Setup

1. Clone the repository:

```bash
git clone https://github.com/connor-bernard/checkpoint-website.git
cd checkpoint-website-backend
```

1. Install dependencies:

```bash
npm install
```

1. Create a `.env` file in the root directory with the following variables:

> [!IMPORTANT]
> The `MONGODB_URI` variable must point to a MongoDB instance. You can use the default value if you have a local instance running on the default port (27017) or set it to the URI of your MongoDB instance.
```env
PORT=3000
MONGODB_URI=mongodb://localhost:27017/checkpoint-db
NODE_ENV=development
```

## Running the Application

### Development Mode

```bash
npm run dev
```

This will start the server with nodemon for hot reloading and run ESLint checks before each reload.

### Production Mode

```bash
npm start
```

## Available Scripts

- `npm start` - Start the production server
- `npm run dev` - Start development server with hot reloading
- `npm run lint` - Run ESLint checks
- `npm run lint:fix` - Run ESLint and automatically fix issues

## Project Structure

```preformatted
src/
├── index.js # Application entry point
├── api/ # API configuration file
├── index.js # Default API router
└── v1/ # APIv1
├── index.js # APIv1 router
├── controllers/ # Controller actions
├── helpers/ # Helper functions
├── interfaces/ # Interface definitions
├── middlewares/ # Middleware functions
├── models/ # Database models
├── routes/ # APIv1 routes
├── services/ # External service integrations
└── validations/ # Request validation schemas
├── config/ # Configuration files
├── db/ # Database configuration
├── lib/ # Library files
└── index.js # Application entry point
```

## Dependencies

### Main Dependencies

- Express - Web framework
- Mongoose - MongoDB ODM
- Cors - Cross-origin resource sharing
- Helmet - Security middleware
- Express Validator - Request validation
- Express Rate Limit - API rate limiting
- Dotenv - Environment variable management

### Dev Dependencies

- ESLint - Code linting
- Nodemon - Development server with hot reload

## License

This project is licensed under the MIT License - see the LICENSE file for details.
134 changes: 134 additions & 0 deletions backend/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/* eslint-disable no-magic-numbers */
import importPlugin from 'eslint-plugin-import';
import globals from 'globals';
import js from '@eslint/js';
import path from 'node:path';

import { FlatCompat } from '@eslint/eslintrc';
import { fileURLToPath } from 'node:url';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

export default [
...compat.extends('eslint:recommended'),
{
plugins: {
import: importPlugin,
},
languageOptions: {
globals: {
...globals.node,
},

ecmaVersion: 12,
sourceType: 'module',
},

rules: {
indent: ['error', 4],
'linebreak-style': ['error', 'unix'],
quotes: ['error', 'single'],
semi: ['error', 'always'],
'consistent-return': 'warn',
'import/no-deprecated': 'error',
'import/no-empty-named-blocks': 'error',
'import/no-extraneous-dependencies': 'error',
'import/no-mutable-exports': 'warn',
'import/default': 'error',
'import/named': 'error',
'import/namespace': 'error',
'import/no-cycle': 'error',
'import/no-self-import': 'error',
'import/no-unresolved': 'error',
'import/no-useless-path-segments': 'error',
'import/first': 'error',
'import/newline-after-import': 'error',
'import/no-duplicates': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }],
'no-unused-expressions': 'warn',
'no-else-return': 'warn',
'no-constructor-return': 'error',
'no-duplicate-imports': 'error',
'no-self-compare': 'error',
'no-unmodified-loop-condition': 'warn',
'no-unreachable-loop': 'warn',
'no-use-before-define': 'error',
'no-useless-assignment': 'warn',
camelcase: 'error',
'capitalized-comments': ['error', 'always'],
'default-case-last': 'error',
'default-param-last': 'error',
'dot-notation': 'error',
eqeqeq: 'error',
'func-style': [
'error',
'declaration',
{ allowArrowFunctions: true },
],
'grouped-accessor-pairs': 'warn',
'max-depth': ['warn', 4],
'max-lines': ['warn', 300],
'max-lines-per-function': ['warn', 30],
'max-nested-callbacks': ['warn', 4],
'max-params': ['warn', 5],
'max-statements': ['warn', 20],
'no-eval': 'error',
'no-implied-eval': 'error',
'no-invalid-this': 'warn',
'no-labels': 'error',
'no-lone-blocks': 'warn',
'no-lonely-if': 'error',
'no-magic-numbers': [
'warn',
{
ignore: [0, 1],
ignoreArrayIndexes: true,
ignoreDefaultValues: true,
enforceConst: true,
},
],
'no-multi-assign': 'error',
'no-negated-condition': 'error',
'no-param-reassign': 'error',
'no-proto': 'error',
'no-unneeded-ternary': 'error',
'no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'no-useless-call': 'error',
'no-useless-computed-key': 'error',
'no-useless-concat': 'warn',
'no-useless-constructor': 'error',
'no-useless-rename': 'error',
'no-useless-return': 'error',
'no-var': 'error',
'object-shorthand': 'error',
'one-var': ['error', 'never'],
'no-warning-comments': [
'warn',
{ terms: ['todo', 'fixme'], location: 'start' },
],
'operator-assignment': ['warn', 'always'],
'prefer-arrow-callback': 'error',
'prefer-const': 'error',
'prefer-exponentiation-operator': 'error',
'prefer-promise-reject-errors': 'error',
'prefer-rest-params': 'error',
'prefer-spread': 'error',
'prefer-template': 'error',
'require-await': 'warn',
'sort-imports': ['warn', { allowSeparatedGroups: true }],
yoda: 'error',
},
},
];
Loading

0 comments on commit e144eed

Please sign in to comment.