Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ All new features should include unit tests. Aim for >85% coverage on service fil
5. Commit with a descriptive message
6. Push and create a pull request

## Architecture Decision Records (ADRs)

We use ADRs to document important architectural decisions. These records are located in the `docs/adr/` directory.

- **Process**: When making a significant architectural change, propose it via a new ADR.
- **Format**: Follow the [Michael Nygard format](https://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions).
- **Immutability**: Once an ADR is accepted, it is immutable. To change a decision, create a new ADR that supersedes the old one.
- **Naming**: Use `NNNN-short-title.md` (e.g., `0008-use-redis-for-caching.md`).

## Project Structure

```
Expand Down
33 changes: 33 additions & 0 deletions docs/adr/0001-record-architecture-decisions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 1. Record architecture decisions

Date: 2025-05-14

## Status

Accepted

## Context

We need to record the architectural decisions made for this project.

## Decision

We will use Architecture Decision Records (ADRs) to document our architectural decisions.
We will follow the format proposed by Michael Nygard.

Each ADR will have:
- Title (NNNN-short-title.md)
- Date
- Status (Proposed, Accepted, Deprecated, Superseded)
- Context
- Decision
- Consequences (Positive and Negative)

ADRs are immutable once Accepted. If a decision is changed, a new ADR will be created to supersede the old one.

## Consequences

- We will have a record of our architectural decisions.
- Future contributors will have context for the decisions made.
- We will be able to see the evolution of our architecture.
- There will be a small overhead in documenting each decision.
29 changes: 29 additions & 0 deletions docs/adr/0002-postgresql-for-relational-data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# 2. PostgreSQL for relational data

Date: 2025-05-14

## Status

Accepted

## Context

The platform handles tips and transactions which require high relational integrity and ACID compliance. We need a reliable database system to manage these records.

## Decision

We chose PostgreSQL over MongoDB.

PostgreSQL is a powerful, open-source object-relational database system that provides strong consistency, complex queries, and robust relational integrity.

## Consequences

### Positive
- Ensures relational integrity for tips, users, and transactions.
- Provides ACID compliance for financial-related data.
- Excellent support for complex queries and indexing.
- Mature ecosystem and widespread developer familiarity.

### Negative
- Schema migrations are required for changes.
- Scaling horizontally can be more complex than with some NoSQL databases.
30 changes: 30 additions & 0 deletions docs/adr/0003-typeorm-for-nest-integration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 3. TypeORM for NestJS integration

Date: 2025-05-14

## Status

Accepted

## Context

We need an Object-Relational Mapper (ORM) to interact with our PostgreSQL database. The project is built using TypeScript and NestJS.

## Decision

We chose TypeORM over Prisma.

TypeORM is a TypeScript-first ORM that integrates natively with NestJS through `@nestjs/typeorm`. It supports the Data Mapper and ActiveRecord patterns, fitting well with NestJS's architectural style.

## Consequences

### Positive
- Native and mature integration with NestJS.
- Excellent TypeScript support and decorators.
- Support for multiple database systems if needed in the future.
- Large community and extensive documentation.

### Negative
- Some complex queries might be harder to express than in raw SQL.
- Performance overhead compared to raw SQL or more lightweight libraries.
- Some might find its API more verbose compared to Prisma.
30 changes: 30 additions & 0 deletions docs/adr/0004-jwt-refresh-tokens-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# 4. JWT with refresh tokens for authentication

Date: 2025-05-14

## Status

Accepted

## Context

We need a secure way to authenticate users and maintain their sessions.

## Decision

We chose JWT with refresh tokens over traditional session-based authentication.

JWTs allow for stateless authentication, which is easier to scale and works well for APIs. Refresh tokens provide a way to maintain user sessions without requiring frequent re-authentication while keeping access token lifetimes short for security.

## Consequences

### Positive
- Stateless and scalable.
- Works well across different domains and mobile apps.
- Short-lived access tokens improve security.
- Refresh tokens allow for seamless UX by renewing access tokens in the background.

### Negative
- Complexity in managing token rotation and revocation.
- Tokens cannot be easily invalidated before they expire (unless using a blacklist).
- Requires secure storage for refresh tokens (e.g., in the database).
31 changes: 31 additions & 0 deletions docs/adr/0005-nestjs-opinionated-framework.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# 5. NestJS as the primary framework

Date: 2025-05-14

## Status

Accepted

## Context

We need a backend framework to build our API.

## Decision

We chose NestJS over Express.

NestJS provides an opinionated structure, built-in Dependency Injection (DI), and excellent TypeScript support out of the box. It is built on top of Express (by default) but adds a layer of abstraction that promotes modularity and maintainability.

## Consequences

### Positive
- Consistent and opinionated project structure.
- Built-in support for Dependency Injection and modularity.
- Strong TypeScript integration.
- Large ecosystem of official and community modules.
- Easier to scale for larger teams and complex codebases.

### Negative
- Steeper learning curve compared to Express.
- More boilerplate code for simple features.
- Heavier framework compared to minimal alternatives.
29 changes: 29 additions & 0 deletions docs/adr/0006-winston-structured-logging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# 6. Winston for structured logging

Date: 2025-05-14

## Status

Accepted

## Context

We need a robust logging system to monitor the application and debug issues.

## Decision

We chose Winston over Pino.

Winston is a versatile and mature logging library with a large number of transports. It has excellent integration with NestJS through `nest-winston`, allowing us to easily replace the default NestJS logger with a structured, multi-transport logging system.

## Consequences

### Positive
- Mature and widely used in the Node.js ecosystem.
- Supports multiple transports (console, file, HTTP, etc.).
- Easy integration with NestJS via `nest-winston`.
- Highly configurable log formats.

### Negative
- Slower than Pino (though usually not a bottleneck for most applications).
- API can be seen as more complex than simpler logging libraries.
32 changes: 32 additions & 0 deletions docs/adr/0007-security-validation-defaults.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# 7. Security and validation defaults

Date: 2025-05-14

## Status

Accepted

## Context

We need to ensure our API is secure and handles request data validation consistently.

## Decision

We chose to use Helmet, Compression, and class-validator as our security and validation defaults.

- **Helmet**: Helps secure the app by setting various HTTP headers.
- **Compression**: Reduces the size of the response body, improving performance.
- **class-validator / class-transformer**: Provides a declarative way to validate and transform request data using decorators on DTOs.

## Consequences

### Positive
- Improved security through standard HTTP headers.
- Better performance with response compression.
- Consistent and robust data validation using NestJS `ValidationPipe`.
- Reduced boilerplate for input validation.

### Negative
- Helmet may require configuration for certain features (like CSP).
- Compression adds some CPU overhead.
- Decorator-based validation can sometimes lead to large DTO files.
17 changes: 17 additions & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Architecture Decision Records (ADRs)

This directory contains the Architecture Decision Records for the StellarTip Backend project.

## Index

- [0001 - Record architecture decisions](0001-record-architecture-decisions.md)
- [0002 - PostgreSQL for relational data](0002-postgresql-for-relational-data.md)
- [0003 - TypeORM for NestJS integration](0003-typeorm-for-nest-integration.md)
- [0004 - JWT with refresh tokens for authentication](0004-jwt-refresh-tokens-auth.md)
- [0005 - NestJS as the primary framework](0005-nestjs-opinionated-framework.md)
- [0006 - Winston for structured logging](0006-winston-structured-logging.md)
- [0007 - Security and validation defaults](0007-security-validation-defaults.md)

## Process

For information on how to contribute and document new architectural decisions, see [CONTRIBUTING.md](../../CONTRIBUTING.md).
Loading