Collaborative full stack project · Backend & integration focus

Evolving a collaborative game backend into a more structured full stack system.

DuckyArena is an educational multiplayer game project built with React, Node.js, Express, PostgreSQL and Docker. My contribution focused on backend architecture, API design, database integrity, infrastructure and frontend integration.

DuckyArena began as a three-person educational project. The system was developed collaboratively across backend modules, database design and application features. My work focused primarily on backend architecture, API design, integration and technical consolidation.

My main contribution was on the backend and integration side of the project. I implemented and expanded REST endpoints, refactored controllers to move PostgreSQL queries into dedicated model layers, introduced reusable validation and error middleware, strengthened database integrity constraints, and Dockerized the backend with automatic PostgreSQL initialization.

As the project evolved, I also added aggregate read endpoints for frontend use cases and implemented the first React-to-API integration path through a shared HTTP client and feature-specific service.

The current system follows a lightweight client-server architecture. React consumes the REST API through a shared HTTP client, while the backend separates routing, HTTP handling and SQL access into distinct layers.

  1. React client
  2. feature service
  3. shared API client
  4. Express routes
  5. middleware
  6. controllers
  7. models
  8. PostgreSQL

Local infrastructure

Docker Compose

  • backend
  • PostgreSQL
  • pgAdmin
  • database/init.sql initializes PostgreSQL
  • backend waits for PostgreSQL health check

Evidence 01 · Backend structure

Separating HTTP from data access

Some backend modules originally executed PostgreSQL queries directly inside controllers. I refactored these modules so controllers handled request/response concerns while dedicated model files owned SQL access.

BeforecontrollerHTTP handling + SQL access
Aftercontroller → model → PostgreSQLHTTP handling / SQL access

Evidence 02 · API design

Designing API responses around frontend needs

I added aggregate read endpoints for use cases such as profile dashboards, player statistics, inventory, rankings and character abilities, reducing the need for the frontend to reconstruct related data from multiple basic requests.

  • GET /api/profiles/:id/dashboard
  • GET /api/profiles/:id/stats
  • GET /api/profiles/:id/inventory
  • GET /api/ranking
  • GET /api/characters/:id/abilities

Evidence 03 · Data integrity

Enforcing data invariants in PostgreSQL

I strengthened relationship tables with database-level constraints that prevent duplicate or invalid states.

  • UNIQUE (match_id, profile_id)
  • UNIQUE (profile_id, cosmetic_id)
  • UNIQUE (profile_id, quest_id)
  • CHECK (profile_id <> friend_id)

Evidence 04 · API consistency

Centralising repeated API concerns

I introduced reusable ID validation and shared 404/error middleware so common validation and error behaviour did not need to be duplicated across individual routes.

  1. request
  2. ID validation
  3. route / controller
  4. 404 / error handling

Some inherited controllers still return direct HTTP 500 responses; error handling is not yet fully centralised.

Evidence 05 · Infrastructure

Making local backend setup reproducible

I Dockerized the Express backend and configured PostgreSQL initialization through database/init.sql, with service health checks coordinating backend startup.

docker compose
  • PostgreSQL → database/init.sql
  • Express backend → DB health check
  • pgAdmin

05

Current status

DuckyArena is still under active development. The backend and PostgreSQL model cover the current game domains, the React application has its initial navigation and the first API-backed feature is connected. Authentication, broader frontend integration, automated tests and CI are still pending.

06

Independent continuation

The project originated in a shared repository. I later continued its technical development in a separate repository to maintain a clearer development path and continue evolving the architecture independently.