A full-stack messaging web application built as the final project for the Web and Software Architecture (WASA) course at Sapienza University of Rome (academic year 2025/2026).
- Authentication: Simplified bearer token authentication (no passwords)
- User profile: create, rename, set and remove avatar
- Direct and group chats: create, rename, change avatar, add/remove members, leave
- Rich Messaging: Send text messages, images, reply to messages, forward messages
- Reactions: React to messages with emojis
- Read Receipts: Single checkmark (delivered), double checkmark (received), colored double checkmark (read)
- Custom UI based on the TokyoNight color scheme
- Backend: Go 1.25, httprouter, SQLite
- Frontend: Vue 3, Vite, Vue Router, Axios, Bootstrap 5 with a custom TokyoNight theme
- Icons: Feather (SVG sprite) and Bootstrap Icons
- API: REST, OpenAPI 3 specification in
doc/api.yaml - Packaging: Docker and Docker Compose
The project follows an API-first approach following this implementation order:
- API contract — the endpoints are defined first in the OpenAPI specification
doc/api.yaml. - Database design — modelled and then restructured for a cleaner implementation (original → restructured).
- Backend — implemented in Go on top of the course template.
- Frontend — a Vue 3 single-page app with a custom theme.
- Packaging — both services are containerized and executed with Docker Compose.
docker compose up --build- API → http://localhost:3000
- Web app → http://localhost:8080
Signing in with a username creates the account automatically if it does not exist.
Backend:
go build -o webapi ./cmd/webapi
./webapi # listens on :3000Frontend:
cd webui
yarn run dev # dev server on http://localhost:5173
# or build the production bundle
yarn run build-prodwasapp/
├── cmd/webapi # application entry point
├── demo/config.yml # default configuration (port, DB path, uploads dir)
├── doc/
│ ├── api.yaml # OpenAPI 3 specification
│ ├── db_schema_original.png
│ └── db_schema_restructured.png
├── service/
│ ├── api/ # one file per HTTP endpoint + shared helpers
│ │ └── reqcontext/ # per-request context (authentication, logger)
│ ├── database/ # SQLite queries, one file per entity
│ └── globaltime/ # server-assigned timestamps
├── webui/
│ ├── public/ # static assets (Bootstrap, Feather sprite, background)
│ └── src/
│ ├── assets/ # global styles and theme
│ ├── components/ # reusable Vue components (ui/ holds the primitives)
│ ├── composables/ # shared state (useUsers, useChats, usePolling)
│ ├── router/
│ ├── services/ # axios instance, auth, API helpers, validators
│ ├── views/ # routed pages
│ ├── App.vue
│ └── main.js
├── Dockerfile.backend
├── Dockerfile.frontend
├── docker-compose.yml
├── go.mod
└── LICENSE
![]() Send a message |
![]() Emoji reactions |
![]() Forward message |
![]() Delete message |
![]() Add member |
![]() Leave / Create group |
- No real authentication — as required by the assignment, login only associates a username with a session token; there is no password or credential check.
- No real-time push — new messages are fetched by polling (every 10 seconds) rather than through WebSockets.
- A small university project, not hardened for production.
Released under the MIT License — see LICENSE. Built on the Fantastic Coffee Decaffeinated template provided by the course.
I used AI tools as a study aid during this project. I designed the architecture and wrote the backend and the API myself, using AI mainly as a mentor to reason through problems and to help with testing. For the frontend I put the component structure together, but the CSS and visual details were refined with AI: it's the area I'm least experienced in, and one I don't intend to pursue professionally.






