This is a simple fullstack newsletter management application to learn and teach fullstack web dev.
Features :
- User regsitration (With verification mail)
- Create newsletters
- Edit / Delete Newsletters
- Let people subscribe/unsubscribe to the newsletter
- Send the subscribed people email newsletters. (Each sent email from a newsletter is called a "letter")
- Ability to save the letter as a draft.
- Send the saved draft letter.
- See all your past sent letters.
- jetpen-frontend/ -> The frontendcode
- services/ -> Backend services
- nginx/ -> Nginx config and Dockerfile
Build the individual services images and the nginx image, after that run :
docker-compose up
In the dev setup we are also using smtp4dev
to have a development email server.
In this section, we see the backend of the application.
⚠ Note that this design is no way meant for scale. This is just to learn few aspects of a backend system not all of them. DONT PUT IT INTO PRODUCTION!
- Database - PostgreSQL 🐘
- Queueing Service - RabbitMQ 🐰
- Microservices ⚙
- Email Service - Sends emails to user, reading from a queue.
- Newsletter Service - Handles saving, editing, deleting newsletters and letters.
- Sub service - Handles subscriptions and unsubscribe
- User service - User authentication and user profile management
- nginx as a API Gateway
- Backend Language - Go 💙
- Library - gofiber ⚡
Used by : User Service
create table jetpen.users(username varchar(50) primary key, email varchar(50) unique not null, name varchar(50) not null, password varchar(1024) not null, "CreatedAt" timestamp default current_timestamp);
create table jetpen.temp_users(username varchar(50) primary key, email varchar(50) unique not null, name varchar(50), password varchar(1024), "CreatedAt" timestamp default current_timestamp, token varchar(1024));
Used by : Newsletter Service
create table jetpen.newsletter (id uuid DEFAULT uuid_generate_v4(), name varchar(50)not null,
description varchar(500),
owner varchar(50) not null,
"CreatedAt" timestamp default current_timestamp,
primary KEY(id), FOREIGN key(owner) REFERENCES jetpen.users(username));
CREATE INDEX idx_jetpen_newsletter ON jetpen.newsletter ("CreatedAt", id, owner);
create table jetpen.letter(id uuid, subject varchar(200) not null, owner varchar(50) not null, content text, nid uuid not null, "CreatedAt" timestamp default current_timestamp, "isPublished" boolean, "PublishedAt" timestamp,primary key(id), FOREIGN key(owner) REFERENCES jetpen.users(username) ON DELETE CASCADE, FOREIGN key(nid) REFERENCES jetpen.newsletter(id));
CREATE INDEX idx_jetpen_letter ON jetpen.letter ("CreatedAt", id);
ADD CONSTRAINT letter_nid_fkey
FOREIGN KEY (nid)
REFERENCES jetpen.newsletter(id)
ON DELETE CASCADE ON UPDATE NO ACTION;
Used by : Sub service
create table jetpen.subscription(id uuid, email varchar(50) not null, nid uuid not null, "CreatedAt" timestamp default current_timestamp, subToken varchar(512),primary key(id), FOREIGN key(nid) REFERENCES jetpen.newsletter(id));
create index idx_jetpen_subscription_nid_email on jetpen.subscription(nid, email);
For frontend we use :
- React
- React Router
- Ant Design
- create react app for tooling and starting template.