https://github.com/viniciusferreira7/fast-feet-api
API built for the fictional delivery company FastFeet, managing the full order lifecycle with features like admin/courier permissions, order tracking, and photo-based delivery confirmation. A reference UI layout is provided to illustrate how the endpoints are consumed.
https://github.com/viniciusferreira7/fast-feet-api
ci-cd clean-architecture ddd docker e2e-tests nestjs openai typescript unit-testing
Last synced: 4 months ago
JSON representation
API built for the fictional delivery company FastFeet, managing the full order lifecycle with features like admin/courier permissions, order tracking, and photo-based delivery confirmation. A reference UI layout is provided to illustrate how the endpoints are consumed.
- Host: GitHub
- URL: https://github.com/viniciusferreira7/fast-feet-api
- Owner: viniciusferreira7
- Created: 2025-12-12T12:51:48.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2026-04-10T13:56:15.000Z (4 months ago)
- Last Synced: 2026-04-10T15:28:48.449Z (4 months ago)
- Topics: ci-cd, clean-architecture, ddd, docker, e2e-tests, nestjs, openai, typescript, unit-testing
- Language: TypeScript
- Homepage:
- Size: 4.99 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# ๐ฆ FastFeet API
> โ ๏ธ **Work In Progress** - This project is currently under active development.
A robust package delivery management system built with NestJS, following Domain-Driven Design (DDD) and Clean Architecture principles.
## ๐ Overview
FastFeet API is a backend application for managing package deliveries, supporting two types of users: delivery persons and administrators. The system handles the complete delivery lifecycle from package creation to final delivery or return.
For detailed requirements and features, see [REQUIREMENTS.md](./REQUIREMENTS.md).
## ๐ ๏ธ Tech Stack
- **Framework**: [NestJS](https://nestjs.com/) v11
- **Runtime**: Node.js 20
- **Package Manager**: pnpm v10.25.0
- **HTTP Server**: Fastify
- **Language**: TypeScript
- **ORM**: Drizzle ORM (PostgreSQL)
- **Password Hashing**: Argon2 (via argon2 package)
- **Email**: Resend API
- **File Storage**: Cloudflare R2 (S3-compatible)
- **Observability**: OpenTelemetry (traces, metrics, logs via OTLP)
- **Schema Validation**: Zod (environment variables)
- **Code Quality**: Biome (linting & formatting)
- **Testing**: Vitest
- **Containerization**: Docker (multi-arch support)
- **CI/CD**: GitHub Actions
- **Semantic Release**: Automated versioning and changelog
## ๐ Getting Started
### Prerequisites
- Node.js 20 or higher
- pnpm 10.25.0 or higher
- Docker and Docker Compose (for local database)
### Installation
```bash
# Install dependencies
pnpm install
# Start PostgreSQL database
pnpm run prestart:dev
# Start development server
pnpm run start:dev
```
## ๐ Available Scripts
```bash
# Development
pnpm run start:dev # Start in watch mode
pnpm run start:debug # Start with debugger
pnpm run prestart:dev # Start PostgreSQL database
# Build
pnpm run build # Build the application
# Production
pnpm run start:prod # Run production build
# Docker
pnpm run docker:build # Build Docker image with git commit tag
pnpm run docker:build:prod # Build production Docker image
# Code Quality
pnpm run check # Run Biome checks
pnpm run check:fix # Fix Biome issues automatically
pnpm run lint # Run Biome linter
pnpm run format # Format code with Biome
pnpm run check:type # TypeScript type checking
pnpm run verify # Pull, test, format, and type-check (pre-commit)
# Testing
pnpm run test # Run unit tests
pnpm run test:watch # Run tests in watch mode
pnpm run test:cov # Run tests with coverage
pnpm run test:debug # Run tests with debugger
pnpm run test:e2e # Run E2E tests
pnpm run test:e2e:watch # Run E2E tests in watch mode
```
## ๐ณ Docker
### Build
```bash
# Build production image
docker build -t fast-feet-api:latest .
# Build for specific architecture
docker build --platform linux/amd64 -t fast-feet-api:amd64 .
docker build --platform linux/arm64 -t fast-feet-api:arm64 .
```
### Run
```bash
# Run container
docker run -p 3333:3333 fast-feet-api:latest
```
The application will be available at `http://localhost:3333`.
## ๐๏ธ Architecture
The project follows:
- **Domain-Driven Design (DDD)**: Organized around business domains
- **Clean Architecture**: Separation of concerns with clear boundaries
- **Domain Events**: Event-driven communication between aggregates
- **RBAC**: Role-Based Access Control for authorization
### Project Structure
```
src/
โโโ core/ # Core building blocks
โ โโโ entities/ # Base entity and aggregate root classes
โ โ โโโ aggregate-root.ts # Base class for aggregates
โ โ โโโ entity.ts # Base entity class
โ โ โโโ value-object/ # Value object base classes
โ โ โโโ pagination.ts # Pagination value object
โ โ โโโ unique-entity-id.ts
โ โ โโโ value-object.ts
โ โโโ events/ # Domain events infrastructure
โ โ โโโ domain-event.ts # Domain event interface
โ โ โโโ domain-events.ts # Domain events dispatcher
โ โ โโโ event-handler.ts # Event handler interface
โ โโโ repositories/ # Core repository abstractions
โ โ โโโ pagination-params.ts
โ โโโ watched-list.ts # Watched list for tracking collection changes
โ โโโ either.ts # Either monad for functional error handling
โ โโโ errors/ # Core error classes
โ โโโ types/ # Core type definitions
โ
โโโ domain/ # Domain layer
โ โโโ delivery/ # Delivery context (bounded context)
โ โ โโโ enterprise/ # Enterprise business rules
โ โ โ โโโ entities/ # Domain entities and value objects
โ โ โ โ โโโ admin-person.ts
โ โ โ โ โโโ delivery-person.ts
โ โ โ โ โโโ recipient-person.ts
โ โ โ โ โโโ email-verification.ts
โ โ โ โ โโโ package.ts
โ โ โ โ โโโ package-history.ts
โ โ โ โ โโโ attachments.ts
โ โ โ โ โโโ package-attachment.ts
โ โ โ โ โโโ value-object/ # Value objects
โ โ โ โ โโโ cpf.ts
โ โ โ โ โโโ verification-code.ts
โ โ โ โ โโโ package-code.ts
โ โ โ โ โโโ package-status.ts
โ โ โ โ โโโ postal-code.ts
โ โ โ โ โโโ package-history-list.ts
โ โ โ โโโ events/ # Domain events
โ โ โ โโโ package-registered-event.ts
โ โ โ โโโ package-assigned-to-a-delivery-person-event.ts
โ โ โ โโโ package-picked-up-event.ts
โ โ โ โโโ package-at-distribution-center-event.ts
โ โ โ โโโ package-is-in-transit-event.ts
โ โ โ โโโ package-is-out-for-delivery-event.ts
โ โ โ โโโ package-was-delivered-event.ts
โ โ โ โโโ package-failed-delivery-event.ts
โ โ โ โโโ package-returned-event.ts
โ โ โ โโโ package-was-updated-event.ts
โ โ โ โโโ package-canceled-event.ts
โ โ โโโ application/ # Application business rules
โ โ โ โโโ use-cases/ # Use cases (application services)
โ โ โ โ โโโ # Authentication & Registration
โ โ โ โ โโโ register-admin-person.ts
โ โ โ โ โโโ register-delivery-person.ts
โ โ โ โ โโโ register-recipient-person.ts
โ โ โ โ โโโ authenticate-admin-person.ts
โ โ โ โ โโโ authenticate-delivery-person.ts
โ โ โ โ โโโ authenticate-recipient-person.ts
โ โ โ โ โโโ # Email Verification
โ โ โ โ โโโ send-admin-person-code.ts
โ โ โ โ โโโ send-delivery-person-code.ts
โ โ โ โ โโโ send-recipient-person-code.ts
โ โ โ โ โโโ validate-admin-person-code.ts
โ โ โ โ โโโ validate-delivery-person-code.ts
โ โ โ โ โโโ validate-recipient-person-code.ts
โ โ โ โ โโโ # Password Management
โ โ โ โ โโโ reset-admin-person-password.ts
โ โ โ โ โโโ reset-delivery-person-password.ts
โ โ โ โ โโโ reset-recipient-person-password.ts
โ โ โ โ โโโ # Person Management
โ โ โ โ โโโ update-admin-person.ts
โ โ โ โ โโโ update-delivery-person.ts
โ โ โ โ โโโ update-recipient-person.ts
โ โ โ โ โโโ get-by-id-admin-person.ts
โ โ โ โ โโโ get-by-id-delivery-person.ts
โ โ โ โ โโโ get-by-id-recipient-person.ts
โ โ โ โ โโโ fetch-many-delivery-person.ts
โ โ โ โ โโโ delete-delivery-person.ts
โ โ โ โ โโโ # Package Management
โ โ โ โ โโโ register-package.ts
โ โ โ โ โโโ update-package.ts
โ โ โ โ โโโ get-package-by-id.ts
โ โ โ โ โโโ get-package-by-code.ts
โ โ โ โ โโโ fetch-many-packages.ts
โ โ โ โ โโโ fetch-packages-near-by-delivery-person.ts
โ โ โ โ โโโ assign-package-to-a-delivery-person.ts
โ โ โ โ โโโ picked-up-package.ts
โ โ โ โ โโโ drop-off-package-at-distribution-center.ts
โ โ โ โ โโโ package-is-in-transit.ts
โ โ โ โ โโโ package-is-out-for-delivery.ts
โ โ โ โ โโโ package-was-delivered.ts
โ โ โ โ โโโ package-failed-delivery.ts
โ โ โ โ โโโ return-package.ts
โ โ โ โ โโโ cancel-package.ts
โ โ โ โ โโโ # Attachments
โ โ โ โ โโโ upload-and-create-attachment.ts
โ โ โ โ โโโ # Package History
โ โ โ โ โโโ register-package-history.ts
โ โ โ โ โโโ errors/ # Use case errors
โ โ โ โ โโโ person-already-exists-error.ts
โ โ โ โ โโโ wrong-credentials-error.ts
โ โ โ โ โโโ email-code-has-not-been-verified-error.ts
โ โ โ โ โโโ time-to-send-new-email-code-error.ts
โ โ โ โ โโโ resource-not-found-error.ts
โ โ โ โ โโโ email-already-in-use-error.ts
โ โ โ โ โโโ same-email-error.ts
โ โ โ โ โโโ same-password-error.ts
โ โ โ โ โโโ only-admin-can-perform-this-action-error.ts
โ โ โ โ โโโ delivery-person-profile-is-disable-error.ts
โ โ โ โ โโโ delivery-person-not-assigned-to-package-error.ts
โ โ โ โ โโโ cannot-disable-delivery-person-with-active-packages-error.ts
โ โ โ โ โโโ package-already-assigned-error.ts
โ โ โ โ โโโ package-already-canceled-error.ts
โ โ โ โ โโโ package-not-assigned-to-delivery-person-error.ts
โ โ โ โ โโโ delivery-without-required-photo.ts
โ โ โ โ โโโ invalid-attachment-type-error.ts
โ โ โ โโโ repositories/ # Repository interfaces
โ โ โ โ โโโ admin-people-repository.ts
โ โ โ โ โโโ delivery-people-repository.ts
โ โ โ โ โโโ recipient-people-repository.ts
โ โ โ โ โโโ packages-repository.ts
โ โ โ โ โโโ packages-history-repository.ts
โ โ โ โ โโโ attachments-repository.ts
โ โ โ โ โโโ package-attachments-repository.ts
โ โ โ โ โโโ email-verifications-repository.ts
โ โ โ โโโ email/ # Email service interfaces
โ โ โ โ โโโ email-sender.ts
โ โ โ โโโ cryptography/ # Cryptography interfaces
โ โ โ โ โโโ hash-generator.ts
โ โ โ โ โโโ hash-comparer.ts
โ โ โ โ โโโ encrypter.ts
โ โ โ โโโ storage/ # Storage interfaces
โ โ โ โ โโโ uploader.ts
โ โ โ โโโ validation/ # Validation interfaces
โ โ โ โโโ cpf-validator.ts
โ โ โ โโโ password-validator.ts
โ โ โ โโโ postal-code-validator.ts
โ โ โโโ errors/ # Domain-specific errors
โ โ โโโ invalidate-cpf-error.ts
โ โ โโโ external-cpf-validation-error.ts
โ โ โโโ invalidate-package-code-error.ts
โ โ โโโ invalidate-package-status-error.ts
โ โ โโโ invalid-postal-code-error.ts
โ โ โโโ external-postal-code-validation-error.ts
โ โ โโโ external-password-validation-error.ts
โ โ โโโ email-code-expired-error.ts
โ โ โโโ invalid-email-code-error.ts
โ โ โโโ delivery-person-already-disabled-error.ts
โ โ โโโ missing-attachment-error.ts
โ โ
โ โโโ notification/ # Notification context (bounded context)
โ โโโ enterprise/ # Enterprise business rules
โ โ โโโ entities/ # Domain entities
โ โ โโโ notification.ts
โ โโโ application/ # Application business rules
โ โ โโโ repositories/
โ โ โ โโโ notifications-repository.ts
โ โ โโโ use-cases/ # Use cases
โ โ โโโ send-notification.ts
โ โ โโโ fetch-many-notifications.ts
โ โ โโโ mark-as-read-notification.ts
โ โ โโโ mark-many-notifications-as-read.ts
โ โโโ subscribers/ # Event subscribers (cross-boundary communication)
โ โโโ on-package-registered-send-notification.ts
โ โโโ on-package-assigned-send-notification.ts
โ โโโ on-package-picked-up-send-notification.ts
โ โโโ on-package-is-at-a-distribution-center-send-notification.ts
โ โโโ on-package-is-in-transit-send-notification.ts
โ โโโ on-package-was-delivered-send-notification.ts
โ โโโ on-package-failed-delivery-send-notification.ts
โ โโโ on-package-was-updated-send-notification.ts
โ โโโ on-package-canceled-send-notification.ts
โ
โโโ infra/ # Infrastructure layer
โโโ auth/ # Authentication module
โ โโโ auth.module.ts
โ โโโ current-user.decorator.ts
โ โโโ jwt-auth.guard.ts
โ โโโ jwt.strategy.ts
โ โโโ public.ts
โโโ cryptography/ # Cryptography implementations
โ โโโ argon-hasher.ts # Argon2 password hashing
โ โโโ argon-hasher.int-spec.ts
โ โโโ jwt-encrypter.ts # JWT encryption
โ โโโ jwt-encrypter.int-spec.ts
โ โโโ cryptography.module.ts
โโโ database/ # Database module
โ โโโ database.module.ts
โ โโโ drizzle/ # Drizzle ORM
โ โโโ drizzle.service.ts # Connection pool management
โ โโโ drizzle.service.int-spec.ts
โ โโโ mappers/ # Domain โ persistence mappers (wip)
โ โโโ repositories/ # Drizzle repository implementations (wip)
โ โโโ schema/ # Table definitions
โ โโโ index.ts
โ โโโ users.ts
โ โโโ delivery-profiles.ts
โ โโโ recipient-profiles.ts
โ โโโ email-codes.ts
โ โโโ packages.ts
โ โโโ package-histories.ts
โ โโโ attachments.ts
โ โโโ notifications.ts
โโโ email/ # Email module (Resend)
โ โโโ build-email-html.ts
โ โโโ email.service.ts
โ โโโ email.service.int-spec.ts
โ โโโ email.module.ts
โโโ env/ # Environment configuration
โ โโโ env.ts # Zod schema for all env vars
โ โโโ env.service.ts
โ โโโ env.service.int-spec.ts
โ โโโ env.module.ts
โโโ http/ # HTTP client module
โ โโโ fetch-http-client.ts # Fetch-based HTTP client
โ โโโ fetch-http-client.int-spec.ts
โ โโโ http.module.ts
โโโ interfaces/ # Shared response interfaces
โ โโโ postal-code-external-service-response.ts
โโโ storage/ # File storage module (Cloudflare R2)
โ โโโ r2-storage.ts
โ โโโ r2-storage.int-spec.ts
โ โโโ storage.module.ts
โโโ validation/ # External validation services
โ โโโ password.service.ts # External password strength validation
โ โโโ password.service.int-spec.ts
โ โโโ postal-code.service.ts # External CEP validation
โ โโโ postal-code.service.int-spec.ts
โ โโโ validation.module.ts
โโโ tracer.ts # OpenTelemetry SDK setup
โโโ app.module.ts
โโโ main.ts
```
### Domain Model
#### Entities
- **AdminPerson**: System administrator with full access
- Manages delivery persons, packages, and recipients
- Can change user passwords
- **DeliveryPerson**: Delivery personnel
- Can pick up and deliver packages
- Can view assigned packages
- Location-based package filtering
- **RecipientPerson**: Package recipient
- Registered in the system to receive packages
- Associated with delivery addresses
- Can track their packages
- **Package**: Delivery package with complete lifecycle
- Unique ULID-based tracking code
- Status management with state transitions
- Assignment to delivery person
- Photo attachment for delivery proof
- Audit trail with timestamps
- Collection of history entries for tracking changes
- **PackageHistory**: Immutable audit log entry for package status changes
- Tracks status transitions (from/to)
- Records author and delivery person
- Includes descriptive notes
- Timestamp of the change
- Implements domain events for event-driven architecture
- **PackageAttachment**: Photo proof of delivery
- **Attachments**: File attachments management
- **Notification**: System notifications for recipients
- Sent when package events occur
- Tracks read/unread status
- Associated with recipient
- **EmailVerification**: Email verification management for user authentication
- Generates unique 8-digit verification codes
- 5-minute expiration window for security
- Tracks validation status (validated/pending)
- Immutable verification tracking
#### Value Objects
- **CPF**: Brazilian tax ID validation
- Format validation (11 digits)
- Check digit verification
- Duplicate digit rejection
- External CPF validation through CpfValidator interface
- Returns `Either` for functional error handling
- **PackageCode**: ULID-based unique identifier
- Lexicographically sortable
- Timestamp-based generation
- Case-insensitive normalization
- Future timestamp validation
- **PackageStatus**: Package lifecycle state management
- **Valid States**:
- `pending` โ Initial state
- `awaiting_pickup` โ Ready for pickup
- `picked_up` โ Assigned to delivery person
- `at_distribution_center` โ At distribution center
- `in_transit` โ On the way
- `out_for_delivery` โ Out for final delivery
- `delivered` โ Successfully delivered (final)
- `failed_delivery` โ Delivery failed
- `returned` โ Returned to sender (final)
- `canceled` โ Canceled (final)
- **State Transitions**: Enforced valid transitions between states
- **Final States**: `delivered`, `returned`, `canceled` (no transitions allowed)
- **PostalCode**: Brazilian postal code (CEP) validation
- Format validation (8 digits with optional hyphen: 12345-678 or 12345678)
- Regex-based pattern matching
- External postal code validation through PostalCodeValidator interface
- Returns `Either` for functional error handling
- **PackageHistoryList**: Collection of package history entries
- Extends WatchedList for tracking changes
- Detects new, removed, and current history entries
- Enables domain event dispatching for new entries
- **VerificationCode**: 8-digit email verification code value object
- Auto-generated using cryptographically secure random integers
- Format validation (exactly 8 digits)
- Lexicographically comparable
- Leading zero preservation
### Domain Events & Subscribers
The application uses domain events for cross-bounded-context communication:
#### Events
- **PackageRegisteredEvent**: Dispatched when a package is registered
- **PackageAssignedToADeliveryPersonEvent**: Dispatched when a package is assigned to a delivery person
- **PackagePickedUpEvent**: Dispatched when a delivery person picks up a package
- **PackageAtDistributionCenterEvent**: Dispatched when a package arrives at a distribution center
- **PackageIsInTransitEvent**: Dispatched when a package is in transit
- **PackageIsOutForDeliveryEvent**: Dispatched when a package is out for delivery
- **PackageWasDeliveredEvent**: Dispatched when a package is successfully delivered
- **PackageFailedDeliveryEvent**: Dispatched when a delivery attempt fails
- **PackageReturnedEvent**: Dispatched when a package is returned to sender
- **PackageWasUpdatedEvent**: Dispatched when package details are updated
- **PackageCanceledEvent**: Dispatched when a package is canceled
#### Subscribers
- **OnPackageRegisteredSendNotification**: Listens to `PackageRegisteredEvent`
- **OnPackageAssignedToADeliveryPersonSendNotification**: Listens to `PackageAssignedToADeliveryPersonEvent`
- **OnPackagePickedUpSendNotification**: Listens to `PackagePickedUpEvent`
- **OnPackageIsAtADistributionCenterSendNotification**: Listens to `PackageAtDistributionCenterEvent`
- **OnPackageIsInTransitSendNotification**: Listens to `PackageIsInTransitEvent`
- **OnPackageWasDeliveredSendNotification**: Listens to `PackageWasDeliveredEvent`
- **OnPackageFailedDeliverySendNotification**: Listens to `PackageFailedDeliveryEvent`
- **OnPackageWasUpdatedSendNotification**: Listens to `PackageWasUpdatedEvent`
- **OnPackageCanceledSendNotification**: Listens to `PackageCanceledEvent`
### Package History
Package history is **automatically created** by the Package entity when state changes occur:
- **Automatic Creation**: No manual use case calls needed
- `package.updateStatus()` โ Creates history entry
- `package.assignDeliveryPerson()` โ Creates history entry
- `package.markAsRegistered()` โ Creates initial history entry
- **Audit Trail**: Each history entry records:
- From/To status transition
- Author (who made the change)
- Delivery person (if applicable)
- Description of the change
- Timestamp
- **Manual History**: `RegisterPackageHistoryUseCase` exists for administrative purposes
- Used for manual corrections or special audit entries
- Not used in normal package lifecycle
### Package Lifecycle Flow
```
pending
โ
awaiting_pickup โโโโโโโโโโโโโโโ
โ โ
picked_up โโโโโโโโโโโโโโโโโโโโโค
โ โ
at_distribution_center โ
โ โ โ
in_transit โโโโโโโโโโโโโโโโโโโโค โ canceled
โ โ
out_for_delivery โโโโโโโโโโโโโโค
โ โ โ
delivered failed_delivery โ
โ โ
returned โโโโโโโโโโ
```
## ๐ Authentication & Authorization
- **JWT-based authentication**: Secure token-based auth
- **Role-Based Access Control (RBAC)**: Permission management
- **Three user roles**: Admin, Delivery Person, and Recipient with different permissions
- **Login with CPF and password**: Brazilian tax ID authentication
- **Password hashing**: Secure password storage using cryptography layer
- **Email verification requirement**: Users must verify their email before authentication
- **Time-limited verification codes**: 5-minute expiration window for security
### User Roles & Permissions
#### Admin
- โ
Create, read, update, delete delivery persons
- โ
Create, read, update, delete packages
- โ
Create, read, update, delete recipients
- โ
Change user passwords
- โ
View all deliveries and packages
#### Delivery Person
- โ
View assigned packages
- โ
Pick up packages
- โ
Mark packages as delivered (with photo proof)
- โ
Mark packages as returned
- โ
View nearby packages based on location
- โ Cannot view other delivery persons' packages
- โ Cannot modify packages not assigned to them
## ๐ CI/CD Pipeline
The project uses GitHub Actions for continuous integration and deployment:
- **Code Quality**: Biome checks, linting, and type checking
- **Testing**: Unit and E2E tests (when enabled)
- **Semantic Release**: Automated versioning and changelog generation
- **Docker**: Multi-architecture builds (linux/amd64, linux/arm64)
- **Docker Hub**: Automated image publishing
## ๐ API Documentation
API documentation is available through Swagger/OpenAPI.
Once the server is running, access the documentation at:
```
http://localhost:3333/api/docs
```
## ๐งช Testing
The project includes three levels of testing with Vitest:
### Unit Tests (`.spec.ts`)
Test domain logic in complete isolation using in-memory repositories and fakes:
- Value object validation (CPF, PackageCode, PackageStatus, PostalCode, VerificationCode)
- Entity logic (EmailVerification expiration, validation status)
- Use case business logic (RegisterAdminPerson, RegisterDeliveryPerson, RegisterRecipientPerson, AuthenticateAdminPerson, AuthenticateDeliveryPerson, AuthenticateRecipientPerson, RegisterPackage, UpdatePackage, AssignPackageToADeliveryPerson, PickedUpPackage, DropOffPackageAtDistributionCenter, PackageIsInTransit, PackageIsOutForDelivery, PackageWasDelivered, PackageFailedDelivery, ReturnPackage, CancelPackage, FetchManyPackages, FetchPackagesNearByDeliveryPerson, ValidatePersonCode, ResetPersonPassword, UpdatePerson, DeleteDeliveryPerson, UploadAndCreateAttachment, FetchManyNotifications, MarkAsReadNotification, MarkManyNotificationsAsRead)
- Email verification requirement in authentication flow
- Domain event subscribers (OnPackageRegisteredSendNotification, OnPackageAssignedToADeliveryPersonSendNotification, OnPackagePickedUpSendNotification, OnPackageIsAtADistributionCenterSendNotification, OnPackageIsInTransitSendNotification, OnPackageWasDeliveredSendNotification, OnPackageFailedDeliverySendNotification, OnPackageWasUpdatedSendNotification, OnPackageCanceledSendNotification)
- Comprehensive test coverage with 200+ passing tests
### Integration Tests (`.int-spec.ts`)
Test infrastructure services against real external systems (database, email, storage, external APIs). Each integration test spins up a NestJS app via `makeModuleRef`:
| Test file | What it covers |
|---|---|
| `drizzle.service.int-spec.ts` | Database connection and query execution |
| `argon-hasher.int-spec.ts` | Argon2 password hashing and verification |
| `jwt-encrypter.int-spec.ts` | JWT sign and verify |
| `env.service.int-spec.ts` | Environment variable loading and validation |
| `email.service.int-spec.ts` | Resend email delivery |
| `fetch-http-client.int-spec.ts` | HTTP client (external service calls) |
| `r2-storage.int-spec.ts` | Cloudflare R2 file upload |
| `password.service.int-spec.ts` | External password strength validation |
| `postal-code.service.int-spec.ts` | ViaCEP postal code lookup |
### E2E Tests
Testing complete user flows, API endpoints, full request/response cycles, and database integration.
### Coverage Reports
Track code coverage metrics with Vitest coverage tools.
### Test Structure
```
test/
โโโ setup-e2e.ts # E2E test setup
โโโ drop-uuid-schema.ts # DB cleanup helper
โโโ cryptography/ # Fake cryptography implementations
โ โโโ fake-hasher.ts
โ โโโ faker-encrypter.ts
โโโ email/
โ โโโ fake-email-sender.ts
โโโ factories/ # Test data factories
โ โโโ make-admin-person.ts
โ โโโ make-delivery-person.ts
โ โโโ make-recipient-person.ts
โ โโโ make-package.ts
โ โโโ make-package-attachment.ts
โ โโโ make-package-history.ts
โ โโโ make-attachment.ts
โ โโโ make-notification.ts
โ โโโ make-module-ref.ts # NestJS app factory for integration tests
โโโ repositories/ # In-memory repository implementations
โ โโโ in-memory-admin-people-repository.ts
โ โโโ in-memory-delivery-people-repository.ts
โ โโโ in-memory-recipient-people-repository.ts
โ โโโ in-memory-packages-repository.ts
โ โโโ in-memory-packages-history-repository.ts
โ โโโ in-memory-notifications-repository.ts
โ โโโ in-memory-attachments-repository.ts
โ โโโ in-memory-package-attachments-repository.ts
โโโ storage/
โ โโโ fake-uploader.ts
โโโ validation/
โ โโโ fake-password-validator.ts
โ โโโ fake-postal-code-validator.ts
โโโ utils/
โโโ generate-future-ulid.ts # ULID generator with future timestamp
โโโ wait-for.ts # Async polling helper for domain events
โโโ assets/
โโโ file-to-use-on-upload.png
```
## ๐๏ธ Database
- **PostgreSQL**: Primary database (managed via Docker Compose)
- **ORM**: Drizzle ORM with `drizzle-orm/node-postgres` driver
- **Automatic Setup**: Run `pnpm run prestart:dev` to start PostgreSQL
- **Environment Variables**: Configure database connection in `.env` file
### Schema Tables
| Table | Description |
|---|---|
| `users` | All user accounts (Admin, DeliveryPerson, RecipientPerson) with role enum |
| `delivery_profiles` | Delivery-person-specific data (`isActive`) |
| `recipient_profiles` | Recipient-specific extension marker |
| `email_codes` | Email verification codes with `validatedAt` tracking |
| `packages` | Package lifecycle data with `packageStatusEnum` constraint |
| `package_histories` | Immutable audit log of package status transitions |
| `attachments` | Uploaded files (delivery proof photos) |
| `notifications` | Recipient notifications with read tracking |
### Required Environment Variables
Create a `.env` file in the root directory:
```env
# Server
PORT=3000
NODE_ENV="dev" # Options: dev, test, production
CORS_ORIGIN="http://localhost:3000"
# JWT (RS256 - Public/Private Key Authentication)
# Generate keys with:
# Private: openssl genrsa -out private_key.pem 2048
# Public: openssl rsa -in private_key.pem -pubout -out public_key.pem
# Then encode to base64:
# JWT_PRIVATE_KEY=$(cat private_key.pem | base64)
# JWT_PUBLIC_KEY=$(cat public_key.pem | base64)
JWT_PRIVATE_KEY="base64-encoded-private-key"
JWT_PUBLIC_KEY="base64-encoded-public-key"
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/fastfeet"
DATABASE_PORT=5432
DATABASE_USERNAME="user"
DATABASE_PASSWORD="password"
DATABASE_NAME="fastfeet"
# Password hashing
ARGON2_PEPPER="random-pepper-string"
# Email (Resend)
RESEND_API_KEY="re_xxxxxxxxxxxx"
EMAIL="noreply@yourdomain.com"
# External services
POSTAL_CODE_EXTERNAL_SERVICE_URL="https://viacep.com.br/ws"
# File storage (Cloudflare R2)
CLOUDFLARE_ACCOUNT_ID="your-account-id"
CLOUDFLARE_ACCOUNT_TOKEN="your-account-token"
AWS_BUCKET_NAME="your-bucket-name"
AWS_ACCESS_KEY_ID="your-access-key"
AWS_SECRETE_ACCESS_KEY_ID="your-secret-key"
# Test environment only
JSON_PLACEHOLDER_URL="https://jsonplaceholder.typicode.com"
HTTPBIN_URL="https://httpbin.org"
```
## ๐ Key Features
### Implemented โ
- Domain entities with DDD principles (AdminPerson, DeliveryPerson, RecipientPerson, Package, PackageHistory, Notification, EmailVerification)
- Value objects with validation (CPF, PackageCode, PackageStatus, PostalCode, VerificationCode)
- Package status state machine with transition rules
- User registration (Admin, Delivery Person, and Recipient)
- Password validation with external validator interface
- Automatic email verification creation
- User authentication use cases (Admin, Delivery Person, and Recipient)
- JWT token generation with encryption layer
- Password comparison with hash comparer
- Credential validation with wrong credentials error handling
- Email verification requirement before authentication
- Time-limited verification codes (5-minute expiration)
- Person management use cases (update, get by ID, fetch many, delete)
- Admin person management
- Delivery person management (with active packages guard on delete)
- Recipient person management
- Password reset use cases for all user types
- Package management use cases
- Package registration with postal code validation
- Package update
- Package retrieval (by ID and by code)
- Package listing with pagination and filtering
- Location-based package filtering for delivery persons
- Package assignment to delivery person with automatic status updates
- Full package lifecycle: pickup โ distribution center โ in transit โ out for delivery โ delivered / failed delivery โ returned
- Package cancellation
- Photo attachment upload for delivery proof (UploadAndCreateAttachment)
- Notification management use cases
- Fetch many notifications (with pagination)
- Mark notification as read
- Mark many notifications as read
- Password hashing with cryptography layer (Argon2 via ArgoHasher)
- JWT encryption implementation (JwtEncrypter)
- Auth module with JWT strategy, guards, and decorators
- External CPF validation with dependency injection pattern
- External postal code validation with dependency injection pattern
- External password strength validation with dependency injection pattern
- File storage abstraction with Uploader interface
- Repository pattern with in-memory implementations for testing
- Domain events infrastructure for event-driven architecture
- Event subscribers for cross-boundary communication
- Package registered notification
- Package assigned notification
- Package picked up notification
- Package at distribution center notification
- Package in transit notification
- Package was delivered notification
- Package failed delivery notification
- Package was updated notification
- Package canceled notification
- Package history tracking with automatic audit trail
- Automatic creation on status changes
- Automatic creation on delivery person assignment
- Manual use case for administrative entries
- WatchedList pattern for tracking collection changes
- Notification system for recipients
- Email verification system with time-limited codes
- 8-digit cryptographically secure verification codes
- 5-minute expiration window
- Validation status tracking
- Send verification code use cases for all user types (Admin, Delivery Person, Recipient)
- Rate limiting to prevent code spam (can't request new code until current expires)
- Email service abstraction with EmailSender interface
- Comprehensive unit tests for domain logic (200+ passing tests)
- Email verification expiration logic tests
- Authentication with unverified email rejection tests
- Verification code format validation tests
- Test data factories for easy test setup with automatic email verification
- Functional error handling with Either monad pattern
### Infrastructure โ
- **Database**: Drizzle ORM with PostgreSQL โ connection pool, schema definitions with enums, indexes, FK constraints
- **Email**: Resend integration for sending verification codes
- **File Storage**: Cloudflare R2 (S3-compatible) for delivery proof photos
- **HTTP Client**: Fetch-based client for external service calls (ViaCEP postal code lookup)
- **Password Validation**: External password strength validation service
- **Observability**: OpenTelemetry SDK with OTLP trace and log exporters
- **Environment**: Zod-validated environment configuration with per-environment rules
- **Integration Tests**: 9 integration test suites covering all infrastructure services
### In Progress ๐ง
- Drizzle repository implementations and domain mappers
- HTTP/REST API endpoints with NestJS controllers
- Package CRUD operations API
- Recipient management API
- Photo upload for delivery proof
- Location-based package filtering
- E2E tests
## ๐ค Contributing
This is a portfolio project, but suggestions and feedback are welcome!
### Development Workflow
1. **Create a new branch**
```bash
git checkout -b feature/your-feature-name
```
2. **Make your changes** following the project conventions:
- Use conventional commits (feat, fix, chore, test, refactor, docs)
- Write unit tests for new features
- Follow the existing code structure and patterns
3. **Run quality checks**
```bash
pnpm run verify
```
4. **Commit your changes**
```bash
git commit -m "feat: add new feature"
```
5. **Push and create a pull request**
```bash
git push origin feature/your-feature-name
```
### Commit Convention
This project uses [Conventional Commits](https://www.conventionalcommits.org/):
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation changes
- `test:` Adding or updating tests
- `refactor:` Code refactoring
- `chore:` Maintenance tasks
- `perf:` Performance improvements
Semantic Release automatically generates versions and changelogs based on commit messages.
## ๐ License
UNLICENSED - This is a course challenge project.
## ๐ค Author
Built as part of a portfolio project based on a course challenge.
## ๐ Acknowledgments
- Course challenge based on Rocketseat's Node.js learning path
- Built with NestJS, following DDD and Clean Architecture principles