Skip to content

Engineering Guidelines

benjamin.dev edited this page Oct 23, 2024 · 1 revision

Engineering philosophy

Our team's engineering approach is grounded in the principles of collaboration, innovation, and quality by adhering to best practices in software development. Here's a summary of our key guidelines:

  • Clean and Readable Code: We prioritize writing clean, readable, and maintainable code that adheres to industry standards and style guides, ensuring consistency across the entire codebase.
  • Test-Driven Development (TDD): Our development process emphasizes Test-Driven Development, allowing us to catch bugs early, validate functionality, and maintain a high level of code quality.
  • Continuous Integration and Deployment (CI/CD): We use CI/CD pipelines to automate testing and deployment, ensuring faster and more reliable releases.
  • Code Reviews and Pair Programming: We conduct regular code reviews and encourage pair programming to share knowledge, improve code quality, and foster a culture of continuous learning.
  • User-Centric Design: Our engineering efforts are guided by a commitment to creating exceptional user experiences, focusing on accessibility, performance, and responsive design.
  • Security and Privacy: We prioritize security and data privacy at every stage of development, incorporating best practices for data protection and secure coding.
  • Documentation and Knowledge Sharing: Comprehensive documentation and knowledge sharing are essential to our process, enabling better onboarding, collaboration, and future development.

By following these guidelines, our team aims to deliver high-quality software that meets user needs, fosters innovation, and aligns with our long-term vision.

Writing Code

Write clear and concise code, while working ensure that the code you are writing is understandable and can be followed by other developers, or yourself in the future. Use the following processes to see if the code you are writing is clear and understandable.

Frontend

Folder Structure

Asozial app follows a common pattern of folder structure for Next.js 14 apps.

root folder

Stores all other folders, config files, env, gitignore.

public

Store image assets divided by categories. Ensure the image is stored is the right category.

src

App's main folder.

actions

Store the server actions functions used to communicate with the backend.

The actions folder contains subfolders for different categories (e.g., user.server, project.server, etc.).

Each subfolder has an index file that exports all actions within that category.

The index file in the main actions folder re-exports the actions from all category subfolders.

This structure allows you to import any action into a component by simply referencing @/actions, streamlining the import process and maintaining cleaner code.

Name the file and folders always with the .server

app

The app folder is the core directory for the App Router in Next.js 14, enabling a new approach to file-based routing.

File-Based Routing:

Each folder within the app directory corresponds to a route segment.

Files like page.tsx within these folders define the individual pages to be rendered at that route.

layout.tsx files provide shared layouts for nested routes, while loading.tsx files define loading states.

For more information about file conventions in Next.js 14: https://nextjs.org/docs/app/building-your-application/routing https://www.youtube.com/watch?v=i6Fa5Oyr59k

components

The components folder is organized by features, creating a clear and modular structure for the application.

common folder:

The common folder is dedicated to storing shared UI components that are reusable across multiple features and pages of the application. Contains generic components like buttons, input fields, modals, cards, and other UI elements that are not tied to a specific feature. Serves as a centralized library for common elements, ensuring consistency in design and functionality throughout the application.

ui folder:

ui folder is dedicated to store all components downloaded from Shadcn

Feature-Based Organization:

Each subfolder within the components directory represents a distinct feature of the application (e.g., auth, dashboard, friendships). This organization makes it easier to locate and manage components related to a specific feature.

Subcategories for Granularity:

Inside each feature folder, there can be additional subcategories to further organize components (e.g.,project/project-form, project/requests). This structure promotes reusability and clarity by grouping related components together.

Component Reusability:

By following a feature-based structure, components are easier to reuse across the application, reducing duplication and promoting consistent design.

This approach fosters a clean, maintainable codebase by aligning components logically with the features they support.

Constants

The constants folder stores shared constant variables (e.g., API endpoints, configuration settings, and fixed values) that are used throughout the application.

Hooks

Custom Hooks are stored here.

Context

Where context logic for Context API files are store.

Lib

db.ts: logic to connect with MongoDB. schema: logic for form validations with Zod library. utils: holds utils functions used for other libraries

Types

Store types shared throughout the app. Divided by categories files.

Utils

holds custom functions to be shared.

auth.ts and middleware.ts

holds logic related to authentication system and middleware.

Variables

Use clear, concise, and self-explanatory names for all variables. camelCase convention

// bad (too generic) const image =

// good const postImage =

Components
  • Write components using function expressions.
  • Use export default for all components.
  • Avoid using arrow functions for component definitions.
  • Adjust imports separated by categories
  • Destructure props at the top level of the component.
  • Define types immediately after import statements.

//Next //import next features

//React //import react hooks

//Actions //import server actions

//Hooks // import any custom hooks or contexts

//Components //any custom components import PageTitle from "../common/ui/PageTitle";

//UI //any shadcn or external library components

//Lib //imports from other libraries

//Utils //imports from utils file

//Constants //import from constants file

//Types //any external file types. eg: User, Project, etc...

type DashboardHeaderProps = { username: string }

function DashboardHeader({username}: DashboardHeaderProps) { return (

Welcome, {username}
); }

export default DashboardHeader;

Functions

Use arrow functions for normal (non-component) functions. Use named exports (export) for all non-component functions.

export const generateSlug = (title: string) => { return title .trim() .toLowerCase() .replace(/[^a-z0-9]+/g, "-") .replace(/^-+|-+$/g, ""); };

//or

export {generateSlug}

Comments

If the task is not easy to comment or not 100% clear, then use comments to provide a brief over view or to communicate to other future developers. Use the following standards to write comments.

Comments that are not required for clarity should be removed before merging to main.

// <- Normal comment this can be used to provide basic context. // ! <- this is an important comment, it will be highlighted in red // * <- This is an enhanced comment, use to provide clear information. It will be highlighted in green // ? <- This is a question, use if unsure or to highlight confustion, these should be seldom used and other methods of clarity should be used e.g. slack or github // TODO: <- Use this to highilight todo tasks.

Backend

Folder Structure

Asozial app follows a common pattern of folder structure for Express.JS apps.

root folder

Stores the src folder, config files, env and gitignore.

src

App's main folder.

config

Stores the server's config files (i.e. cloudinary).

models

Stores the data models of the application, typically representing the schema definitions for MongoDB.

db

Contains the database connection setup and configuration

routes

Stores the application's route handlers, which define the endpoints and their respective logic. Each file within this folder corresponds to a specific feature in the app.

The routes folder contains subfolders for different categories (e.g., Projects, Users, Messages, etc.).

Each subfolder has an index file that exports all the endpoints within that category.

The index file in the main routes folder re-exports all the route handlers from all the subfolders into the app.ts.

utils

Stores utility functions or helper files that are used across the app. These includes functions for formatting.