A web based chat platform.
Circlechat is a web based chat application. The core service provided is the instant transmission of messages between users.
In Circhechat, users can
- login, register, and edit their profile
- create channels and update the channels they created
- send messages to channels and edit their own messages
- view whether other users are online
Whenever a channel, message or profile's data is changed it is updated in real time on all clients. This means that when a user updates her profile description, or posts a message, all clients are notified and update the view accordingly.
Circlechat is orchestrated through docker. There are 4 containers:
- client: a react-redux javascript client
- web: a REST API and websocket server written in nodeJS
- nginx: an nginx server and reverse proxy, which either serves the client application or routes requests to the API server
- db: a postgresql database
The application can be deployed in two environments:
-
dev, meant for development. Features include automatically restarting the client and webserver on code changes for fast development.
-
production, optimized for user-facing deployment. For instance, the client is built and minified.
While the client served to all devices, mobile and desktop alike, the view is adapted to the screen size. The mobile layout makes use of touchscreen features, such as swiping between views. On larger screens, more information is displayed.
The client is a single page application, build with react (+react router) and redux. The layout is implemented with css grid.
- available under two color themes (light and dark).
- infinite scroll: more messages are fetched when the user has scrolled to the top of a chat.
- loading bars indicate that a server response is pending.
The store is unit-tested with jest with docker-compose run client npm test
The web container is a nodeJS applcation responsible for the rest API and websockets.
The codebase is separated into modules (auth, profiles, channels, messages). Each module is made up of:
- a
service
file which handles database interactions - a
router
file where express API routes are defined - an
events
file which subscribes to websocket events
It is unit tested with mocha with docker-compose run web npm test
endpoint | method | request body | response body | description |
---|---|---|---|---|
/api/v1/auth/login/ |
POST |
{email, pw} |
{token, userId, lastLogoutAt} |
login with userId or email. The response includes a JWT token to be sent back with every subsequent request |
/api/v1/auth/ |
POST |
{email, pw |
none |
register a new user |
/api/v1/auth/password |
PUT |
{currentPw, newPw} |
{user} |
update a user's password |
/api/v1/auth/email |
PUT |
{pw, newEmail} |
{user} |
update a user's email |
/api/v1/auth/:id |
GET |
none |
{userId, email} |
get a user's information |
/api/v1/auth/:id |
DELETE |
none |
none |
delete a user |
api/v1/channel/ |
POST |
{profileId, name} |
{profileId, name, createdAt, updatedAt} |
create a channel for profile with id |
api/v1/channel?id |
GET |
none |
{profileId, name, createdAt, updatedAt} |
get a channel's information |
api/v1/channel/ |
PUT |
{name} |
{id, updatedAt} |
update a channel |
api/v1/channel? |
DELETE |
none |
none |
delete a channel |
api/v1/channel/all |
GET |
none |
{channels: [{profileId, name, createdAt, updatedAt}] |
update a channel |
api/v1/message/ |
POST |
{profileId, channelId, text} |
{profileId, channelId, text, createdAt, updatedAt} |
create a new message for user in channel |
api/v1/message?id |
GET |
none |
{profileId, channelId, text, createdAt, updatedAt} |
get a message |
api/v1/message?id |
PUT |
{text} |
{profileId, channelId, text, createdAt, updatedAt} |
update a message |
api/v1/message?id |
DELETE |
none |
none |
delete a message |
api/v1/message/all?id?n?after |
GET |
none |
{messages: [{profileId, channelId, text, createdAt, updatedAt}], hasMore} |
get n or all messages maybe after a specific message, in a channel or in all channels |
api/v1/profile/ |
POST |
{userId, name?, description?, status?} |
{userId, name, description, status} |
create a new profile |
api/v1/profile?id |
GET |
none |
{userId, name, description, status} |
get profile with id |
api/v1/profile?userId |
GET |
none |
{userId, name, description, status} |
get the profile of a user |
api/v1/profile?id |
PUT |
{name, description, status} |
{userId, name, description, status} |
update profile with id |
api/v1/profile?id |
DELETE |
none |
none |
delete profile with id |
api/v1/profile/all |
GET |
none |
{profiles: [{userId, name, description, status}]} |
get all profiles |
-
start in dev environment
- create a docker machine
- create a .env file (see docker-compose.yml for the required variables)
docker-compose -f docker-compose.dev.yml build
- run
docker-compose -f docker-compose.dev.yml run web node app/manage/create
to create the database tables docker-compose -f docker-compose.dev.yml up
-
start in prod environment
- create a docker machine
- create a .env file (see docker-compose.yml for the required variables)
docker-compose build
- run
docker-compose run web node app/manage/create
to create the database tables docker-compose up -d
Currently, circlechat is a MVP. All desired features have yet to be implemented. Namely, all chat and profile features are present, but there exists only one global circle: all users are automatically added to a global circle, which holds all channels and profiles. The next major development step is the implementation of user-created circles, each with their own channels and profiles.