Introduction
Team $100K MRR: Nathan Lodge and Slater Leonardo.
This book is the project wiki: status reports, Gantt, presentations, specs, and how to log in or deploy. The live site is emotial.app.
Use the sidebar. Planning is the first 10 weeks (proposal, diagrams, wireframes). Implementation is the coding quarter.
Intro to Senior Project
The first 10 weeks: proposal, diagrams, wireframes, and Gantt. There is no week 10 status report.
Week 1 is the proposal. Status reports start at week 2.
$100K MRR - Project Proposal (Planning Week 1)
Team Name
$100K MRR
Team Members
- Nathan Lodge
- Slater Leonardo
Business Opportunity / Problem
Social Media Web Application
Users
Our users will be anyone who is interested in using a social media site to stay social. In reality, it will be mostly NEIT students.
User Requirements
Non-Logged-In Users
- View Posts
- View Timeline
- Advanced Timeline Management
- Sort Timeline
- Filter Timeline
- Search Posts
- View Profiles
- Sign up
- Log in
- Reset Password (maybe, if we choose to use Resend for sending emails)
- Change Website Theme
Users
- Post Management
- React to Post
- Create Post
- Edit Post
- Delete Post
- Share Post
- Reply to Post
- Add an Image to a post (up to 4)
- Add animated images (gifs)
- Video uploading (max 1)
- Rich Post Functionality
- Mentioning
- Hashtags
- Reaction List
- Other Users Management
- Follow User
- View Other User's Followers
- Profile Management
- Add Profile Picture
- Animated Profile Pictures (gifs)
- Add Banner
- Update Bio
- Update Username / Display Name
- Update Password
- Notifications
- Get notified when another user reacts to your post
- Get notified when another user follows you
- Get notified when another user replies to your post
- Live Events
- Real-time notifications via WebSockets
- Developer Tools
- Ability to create a bot
- API access for programmatic interaction
- Profile Badges
- Admin Badge
- Follower Badges: 10+, 25+, 100+
Admins
- View All Profiles
- View Reports
- Delete Accounts
- Delete Posts
Technology Stack
Frontend
- Next.js / React
- Tailwind CSS
- TypeScript
- Socket.io Client
Backend
- Golang
- Gin
- Gorm
- Socket.io
Infrastructure
- PostgreSQL
- Docker
- Minio S3 (maybe, for image blob storage)
Services
- GitHub
- Cloudflare
- Resend (maybe, for emails)
- Google (maybe, for Google OAuth logins)
High Level Database Architecture
- Users
- Posts
- Notifications
- Relationships (Followers / Following)
- Reactions (our version of Likes)
- Shares
- Reports
$100K MRR - Status Report: Planning Week 2
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 1 |
| Slater Leonardo | 1 |
Completed Tasks
| Task | Owner |
|---|---|
| Completed project proposal | Both |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 1 | 1 |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Start designing a mockup for the prototype due Week 4 | Both |
| Complete use cases diagram | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management with work | Medium |
| Easter holiday | Medium |
Overdue Tasks
- N/A
Issues
- Running out of time to design prototype.
Follow-up Actions
| Action | Responsible Person |
|---|---|
| Finalize what the social media platform is going to look like | Both |
| If prototype isn't done by Week 4, continue working on it | Both |
$100K MRR - Status Report: Planning Week 3
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 5 |
| Slater Leonardo | 5 |
Completed Tasks
| Task | Owner |
|---|---|
| Use cases diagram | Both |
| Started wireframe | Nathan |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Use cases diagram | 1 hr | 1 hr | |
| Wireframe | N/A | 4 hrs |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Continue wireframe | Nathan |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Gantt chart | Medium |
| Wireframe | Low |
| Database design | Low |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| Continue wireframe | Nathan |
| Start Gantt chart | Both |
Use Cases
Overview

Post Management

Profile Management

Timeline

$100K MRR - Status Report: Planning Week 4
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 10 |
| Slater Leonardo | 5 |
Completed Tasks
| Task | Owner |
|---|---|
| Start wireframe | Nathan |
| Start 10-week Gantt chart | Nathan |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 10 | 10 |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Complete midterm presentation | Nathan |
| Complete ERD | Slater |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management with work | Medium |
| Slater's sister's birthday | Low |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| Continue wireframe | Nathan |
| Database design / ERD | Slater |
Prototype
Feed

Explore

Notifications

Profile

Settings

$100K MRR - Status Report: Planning Week 5
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 7 |
| Slater Leonardo | 10 |
Completed Tasks
| Task | Owner |
|---|---|
| Frontend wireframe and Gantt chart | Nathan Lodge |
| ERD and database design | Slater Leonardo |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 20 | 17 | 3 |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Activity diagram | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Low |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| Continue work on wiki | Both |
Entity Relationship Diagram
Gantt Chart

$100K MRR - Status Report: Planning Week 6
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 2 |
| Slater Leonardo | 5 |
Completed Tasks
| Task | Owner |
|---|---|
| Activity diagram | Slater |
| Continue design | Nathan |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Class diagrams | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Family health issues | Medium |
| Nathan's work schedule | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
Activity Diagrams
Account Access

Create Post

Timeline & Post Interaction

Follow / Unfollow User

$100K MRR - Status Report: Planning Week 7
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 3 |
| Slater Leonardo | 3 |
Completed Tasks
| Task | Owner |
|---|---|
| Class diagram | Both |
| Keep experimenting with wiki | Both |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Heuristic evaluation | Both |
| Improve design | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Family health issues | Medium |
| Time management | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
Class Diagram
$100K MRR - Status Report: Planning Week 8
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 3 |
| Slater Leonardo | 2 |
Completed Tasks
| Task | Owner |
|---|---|
| Heuristic evaluation | Nathan Lodge |
| Heuristic evaluation | Slater Leonardo |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 10 | 5 | 3 |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Activity diagram | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Low |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
Heuristic Evaluation
1. Visibility of system status
The sidebar will have the current page you're on highlighted and when actions are performing liked creating a post or editing your account settings, navigation and text displayed will allow users to understand where they are and that their actions went through.
2. Match between system and the real world
The site already looks like common social media sites and has common symbols users like recognize like a magnifying glass for searching, house for home page, etc. Additionally, one of the core features of emotial are the emoji reactions which are meant to mirror real reactions people have.
3. User control and freedom
Users will be able to sign out, delete their accounts, edit their posts, unreact to posts, unfollow a profile, etc. All of these are examples of a user being able to reverse their actions.
4. Consistency and standards
Many pages will reuse the same shared layout (navigation on the left, content in the middle, friends/trending content on the right) which is coherent. Also, typography and common cards will be built so that the app has a uniform look.
5. Error prevention
On forms like login and signup there will be danger borders and labels showing validation errors, there will able be zero states for example on search showing that their search returned no results so that users are always in the loop.
6. Recognition rather than recall
There are explicit buttons/labels for actions that may not be obvious and common elements have common interactions across pages. This will make it easy for users to recognize how to interact with elements.
7. Flexibility and efficiency of use
The timeline and profiles will work well for both writing posts and browsing/reading posts. There will also be power user options like sorting by reaction and options like that. This adds flexibility to what users can do while meeting everyones needs.
8. Aesthetic and minimalist design
Emotial has a simple but consistent and explicit user interface. There are buttons for common operations and dropdown menus for more complex operations. The typography is consistent across components and is easy on the eyes.
9. Help users recognize, diagnose, and recover from errors
There was be clear danger borders and labels showing when an error has occurred. for example, invalid password or post text is too long. One really important one is file size too big for images/videos. If they silently fail to upload with no visual indicator that is bad.
10. Help and documentation
There's no documentation or help section yet, but we plan on having a sort of onboarding modal appear when you login for the first time that shows the common actions users can perform. Maybe we will add a support button / help section at some point too.
$100K MRR - Status Report: Planning Week 9
Project Summary
Emotial is a social media platform with a unique emoji reaction system, videos, animated profile pictures, and more.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 5 |
| Slater Leonardo | 5 |
Completed Tasks
| Task | Owner |
|---|---|
| Final Wiki | Both |
| Final Gantt chart | Both |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 10 |
Planned Tasks for Next Week
| Task | Owner |
|---|---|
| Final Presentation | Both |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management with other finals | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
Gantt Chart

Senior Project
The next 10 weeks: building and shipping Emotial. There are no week 1 or week 10 status reports.
The site went live at emotial.app in week 9.
$100K MRR - Status Report: Implementation Week 2
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 10 |
| Slater Leonardo | 5 |
Completed Tasks
| Task |
|---|
| Start mocking UI pages with React |
| Start API implementation |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 15 | 15 |
Planned Tasks for Next Week
| Task |
|---|
| Continue working on UI and API and getting ready to connect them |
| Set up development/staging database |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 3
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 10 |
| Slater Leonardo | 10 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Set up development PostgreSQL instance |
| Set up development Minio instance |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 20 | 20 |
Planned Tasks for Next Week
| Task |
|---|
| Continue working on API to get it ready to connect to frontend |
| Keep working on UI pages on frontend using a mock API |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 4
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 15 |
| Slater Leonardo | 10 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Advanced frontend features: image uploading, GIFs, banners, post modal, and more |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 25 | 25 |
Planned Tasks for Next Week
| Task |
|---|
| Continue working on API to get it ready to connect to frontend |
| Keep working on UI pages on frontend using a mock API |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 5
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 10 |
| Slater Leonardo | 15 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Lots of backend API/controller wiring |
| More frontend features: auth pages, emoji packs, and themes |
| Started wiring API with web app |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 25 | 25 |
Planned Tasks for Next Week
| Task |
|---|
| Continue improving backend/frontend features |
| Continue wiring API with web app |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
| Nathan going on vacation for a week | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 6
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 15 |
| Slater Leonardo | 15 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Continue backend API/controller wiring |
| Lots of frontend polish to make the app feel nicer to use: preloaders, animations, etc. |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 30 | 30 |
Planned Tasks for Next Week
| Task |
|---|
| Continue improving backend/frontend features |
| Continue wiring API with web app |
| Continue using/testing web app to make sure it feels nice to use, and polish what doesn't |
| Automated integration tests (Playwright) |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
| Nathan going on vacation for a week | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 7
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 15 |
| Slater Leonardo | 15 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Continue backend API/controller wiring |
| Lots of frontend polish to make the app feel nicer to use: preloaders, animations, etc. |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 30 | 30 |
Planned Tasks for Next Week
| Task |
|---|
| Continue improving backend/frontend features |
| Continue wiring API with web app |
| Work on OpenAPI docs |
| Continue using/testing web app to make sure it feels nice to use, and polish what doesn't |
| Automated integration tests (Playwright) |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
| Nathan going on vacation for a week | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 8
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 20 |
| Slater Leonardo | 15 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Continue backend API/controller wiring |
| Used feedback from Emotial beta testers to improve the web app |
| Working media uploads |
| Generated Open Graph images |
| Improved reactions system and replies system |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 35 | 35 |
Planned Tasks for Next Week
| Task |
|---|
| Continue improving backend/frontend features |
| Continue wiring API with web app |
| Continue using/testing web app to make sure it feels nice to use, and polish what doesn't |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
| Other finals | Medium |
| Scope creep | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
$100K MRR - Status Report: Implementation Week 9
Project Summary
A social media site with a unique reactions system.
Team Members
| Member | Hours This Week |
|---|---|
| Nathan Lodge | 15 |
| Slater Leonardo | 15 |
Completed Tasks
| Task |
|---|
| Continue API implementation |
| Continue website implementation |
| Continue backend API/controller wiring |
| Used feedback from Emotial beta testers to improve the web app |
| Live at https://emotial.app |
Time Tracking
| Planned | Actual | Remaining Budget | |
|---|---|---|---|
| Hours | 30 | 30 |
Planned Tasks for Next Week
| Task |
|---|
| Continue using/testing web app to make sure it feels nice to use, and polish what doesn't |
| Final changes to get ready for presentation |
| Create presentation |
Project Risks
| Risk | Severity (High / Medium / Low) |
|---|---|
| Time management | Medium |
| Scope creep | Medium |
Overdue Tasks
- N/A
Issues
- N/A
Follow-up Actions
| Action | Responsible Person |
|---|---|
| N/A |
Gantt chart
This is the 20-week Gantt from the end of Intro to Senior Project (dated May 18, 2026). It covers both quarters: planning (March to May) and implementation (June to September). We did not make a second chart just for the coding quarter.
Planning tasks are marked complete. Implementation was still at 0% when we exported it, because that half was the plan for this quarter. Those tasks are done now, except the final presentation.
The midterm version from planning week 5 only covered the first quarter. That one is under Planning week 05.
Full project (both quarters)

What the implementation bars were
| Planned task | Planned window |
|---|---|
| Repository / project setup | Jun 1 to 12 |
| Database and backend setup | Jun 15 to 19 |
| Authentication | Jun 22 to 26 |
| Frontend setup | Jun 29 to Jul 3 |
| Post system | Jul 6 to 10 |
| Timeline and feed | Jul 13 to 17 |
| Profile and relationship features | Jul 20 to 24 |
| Image / video uploading | Jul 27 to 31 |
| Live notifications | Aug 3 to 7 |
| Admin features | Aug 10 to 14 |
| Developer features | Aug 17 to 21 |
| Deployment / Docker | Aug 24 to 28 |
| Testing / bug fixes | Aug 31 to Sep 18 |
| Final presentation | Sep 21 to 25 |
Frontend and API work actually ran in parallel from implementation week 2, not in that strict order. The site went live at emotial.app in implementation week 9.
Midterm presentation (Intro to Senior Project)
Social Media Web Application
$100K MRR Team
Team members
Slater Leonardo
- API
- Database
Nathan Lodge
- Frontend Developer
- Designer
Project overview
This will be a full featured social media with a unique emoji reaction system.
Including everything you'd expect like:
- User accounts
- Posts (with images, GIFs, or a video)
- Reactions
- Replies
- Sharing
- Hashtags/mentions
It will also support extra features like realtime notifications, a developer bot API, and multiple themes to choose from.
Tech stack
Frontend
- Next.js / React
- Tailwind CSS
- TypeScript
- Socket.io Client
Backend
- Golang
- Gin (Go API Router)
- Gorm (Go ORM)
- Socket.io Server
Infrastructure
- PostgreSQL
- Docker
- Minio S3 (Blob Storage)
Services
- GitHub
- Cloudflare
- Google OAuth (maybe)
Gantt chart


Use case diagram

Post management

Profile management

Timeline

ERD: Account

ERD: Posts

ERD: Admin

Wireframe (Feed)

Wireframe (Explore)

Wireframe (Notifications)

Wireframe (Profile)

Wireframe (Settings)

Final presentation (BS Capstone)
Team introduction
Nathan Lodge
- Role: Frontend Developer, Designer, DevOps
- Responsibilities: Design and build frontend, deploy app
Slater Leonardo
- Role: Backend Developer, DB Admin
- Responsibilities: Build API, design database
Emotial overview
The social platform for sharing your thoughts and feelings.
- Full featured text-based social media
- Unique emoji reaction system
- User accounts
- Avatars / banners
- Following / friends
- Posts (with images, GIFs, or a video)
- Replies
- Sharing
- Hashtags / mentions
- Realtime notifications
- Multiple themes
Timeline
| Week | Highlights |
|---|---|
| 1 | Init frontend and backend, wired up boilerplate, set up hosting |
| 2-3 | Profiles, avatars / banners / media, followers, search, live notifications, basic mobile layout |
| 4 | Auth pages and login / signup, set up themes |
| 5 | Frontend polish, Docker / CI, account settings, and media cropping |
| 6 | Admin functionality, mentions / hashtags, emoji styles |
| 7 | Shares, emoji picker, image uploading / CDN, Open Graph, reaction list |
| 8 | Feed sorting, theme accents, friends / suggestions, drag-and-drop media |
| 9 | Live new post updates, crop / zoom polish, and remaining bug fixes |
Database ERD

Obstacles overcome
Frontend
- Rich text editor with mentions, hashtags, and links
- Media normalization / uploading in the background
- Type safety between frontend and backend
- Emoji styles
Backend
- Creating an OpenAPI specification
- Server-sent events
- PostgreSQL on a large scale application
Technical design
Frontend
- Next.js app with React client components fetching data via TanStack Query
- API client generated from the backend's OpenAPI spec, keeping types in sync automatically
- User interactions update the UI optimistically, then sync with the server in the background
- Live feed and notification updates arrive over server-sent events
Backend
- Go REST API built on Gin and Huma. Huma generates the OpenAPI spec from models and handlers
- API handlers to service layer to GORM to Postgres
- Auth with JWTs stored as a cookie
- Live feed and notification updates are pushed over server-sent events
Deployments We deploy the app on one of Slater's servers. We use Docker to deploy frontend, backend, Postgres, and MinIO containers, which all connect over the local network.
Summary
Overall this project was fun for us. We had a lot of support and good ideas going in, so our focus was on executing and making the platform feel nice to use.
Live Demo
Sharing on Mobile

Open Graph

How to log in
Live site: https://emotial.app
You can browse the feed and profiles without an account. To post, react, follow, or reply, you need one.
Create an account
- Go to https://emotial.app/signup.
- Enter a display name (what people see on your profile).
- Enter a username (letters, numbers, and underscores only; 3-16 characters). It is stored lowercase.
- Enter an email.
- Enter a password (at least 8 characters).
- Click Create account.
You land on the feed, signed in. There is no email confirmation.
Log in later
- Go to https://emotial.app/login.
- Enter your email or username.
- Enter your password.
- Click Log in.
What to try
- Feed (
/): write a post, add images or a video, react with emoji, reply, share. - Explore (
/explore): search posts and people. - Notifications (
/notifications): follows, replies, and reactions on your posts. - Profile: open Profile in the sidebar to edit your avatar, banner, and bio.
- Settings (
/settings): email, password, theme.
To sign out, use Log Out in the sidebar.
How to deploy
Emotial runs as four Docker containers on one network: web, api, postgres, and minio. That is how production runs on Slater's server. The live site is https://emotial.app.
The Dockerfiles are source/web/Dockerfile and source/api/Dockerfile. source/docker-compose.yml starts all four.
What you need
- Docker with Compose
- About 4 GB of disk for the images
Start the stack
From submission/source/:
- Start Postgres and MinIO.
docker compose up -d postgres minio
- Apply the schema. The API connects to Postgres but does not create tables.
docker compose exec -T postgres psql -U emotial -d emotial -v ON_ERROR_STOP=1 < schema.sql
- Build and start the API and web app.
docker compose up -d --build api web
- Open http://localhost:3000. Create an account using the login instructions.
| Service | URL |
|---|---|
| Web | http://localhost:3000 |
| API health | http://localhost:8080/health |
| MinIO API (media) | http://localhost:9000 |
| MinIO console | http://localhost:9001 |
MinIO console: user emotial, password emotial-minio-secret. The API creates the emotial bucket when it starts.
Stop
docker compose down
Add -v if you want to delete the Postgres and MinIO volumes too.
How the containers talk
The browser loads the web app on port 3000 and calls the API on port 8080.
The API reaches Postgres as hostname postgres and MinIO as minio:9000.
Browsers load uploaded images from http://localhost:9000/emotial/... (path-style), not from the Docker hostname.
NEXT_PUBLIC_API_BASE_URL is set when the web image is built. If you change the public API URL, rebuild web.
Production notes
On a public host, change these in the compose file (or whatever you use to run it) before you go live:
EMOTIAL_SERVER_ALLOW_ORIGINSandEMOTIAL_SERVER_APP_URLtohttps://your-domain- Web build args
NEXT_PUBLIC_APP_URLandNEXT_PUBLIC_API_BASE_URLto those public URLs EMOTIAL_AUTH_JWT_SECRETto a new value (openssl rand -hex 32)EMOTIAL_AUTH_SECURE_COOKIEStotrueEMOTIAL_MEDIA_PUBLIC_URLto the URL browsers use for objects (a CDN origin, or the published MinIO host)- Postgres and MinIO passwords
The API image build compiles with libvips (HEIF/AVIF) and runs the media tests during docker build.
Emotial functional specification
Team: $100K MRR (Nathan Lodge, Slater Leonardo)
What the live product does. How it is built is in the technical specification. Site: emotial.app.
Purpose
Emotial is a social site for sharing thoughts and feelings. Reactions are emoji, not a single like. We built it for students and anyone who wants a small, familiar feed.
Actors
| Actor | Can |
|---|---|
| Guest | Read the feed, explore, and profiles. Sign up or log in. Change theme. Cannot post, react, follow, reply, or report. |
| User | Everything a guest can, plus write and manage their own posts, react, follow, share, reply, upload media, and get notifications. |
| Admin | Everything a user can, plus review reports and close accounts or delete posts. |
Accounts
Sign up: display name, username, email, password. There is no email confirmation. Username is 3-16 characters (letters, numbers, underscore), stored lowercase. Password is at least 8 characters.
Log in with email or username plus password. Log out from the sidebar.
Settings: email, password, theme / accent. Closing the account needs the current password. That retires the username for good and frees the email.
Username does not change after sign up. Display name and bio do.
Posts
A post has a body (up to 500 characters) and optional media.
You can create, edit, and delete your own posts. A deleted post stays in a thread as a tombstone (no author, no body).
You can reply (one hop on a profile; the full thread is on the post page) and share (outbound only). @username notifies that user. #tag is searchable.
Media: up to 4 images (including GIFs) or 1 video. Upload finishes in the background, then the files attach to the post.
The body can include emoji and ordinary links.
Reactions
A user puts one emoji reaction on a post. It is not a like count. They can change it or take it off. Anyone can open the list of who reacted.
Feed sorts: recent, trending, and by emotion (funniest, saddest, maddest, shocking).
People
Follow and unfollow. See followers, following, and friends (mutual follows).
A profile shows avatar (can be animated), banner, display name, username, bio, posts, and replies.
You can report a post or a profile for harassment, spam, or inappropriate content.
Feed, explore, notifications
Feed (/): posts from the network, with live updates when new posts arrive.
Explore (/explore): search posts and people. Recent searches are kept.
Notifications: reaction on your post, reply, follow, mention. Unread count updates live. You can mark one or all read.
Admin
List profiles. List reports and resolve them. Close an account or delete a post.
Guest vs signed-in
| Surface | Guest | User |
|---|---|---|
| Feed / Explore / Profile | Yes | Yes |
| Composer, react, follow, reply, share, report | Prompt to log in | Yes |
| Notifications / Settings | Redirect to log in | Yes |
| Admin | No | Admin only |
Not in this build
Password reset email, Google OAuth, bot accounts, follower badges, and Socket.io were in the proposal and did not ship. Live updates use server-sent events.
Emotial technical specification
Team: $100K MRR (Nathan Lodge, Slater Leonardo)
This is how the live site at emotial.app is built. What users can do is in the functional specification.
Overview
Emotial is a social web app, mostly text. Guests can read the feed and profiles. Users can post, reply, react with emoji, follow people, and get live notifications. Images, GIFs, and video go in MinIO. Production is four Docker containers on one machine: web, API, Postgres, and MinIO.
Architecture
Browser (Next.js)
| HTTPS + cookie
v
Web :3000 API :8080
| \
v v
Postgres MinIO (S3)
The browser calls the API directly (credentials: include). CORS allows the web origin.
The session is a JWT in an HttpOnly cookie named emotial_sess. If a client cannot store cookies, it can send Authorization: Bearer.
Live feed and notification updates are server-sent events, not WebSockets. The proposal listed Socket.io. We shipped SSE instead.
Huma builds an OpenAPI document from the Go handlers. The web app generates its TypeScript client and TanStack Query options from that document with pnpm openapi-ts.
On the API, a request goes handler to service to GORM to Postgres.
Stack
| Layer | Choice |
|---|---|
| Web | Next.js 16, React 19, TypeScript, Tailwind CSS 4 |
| Data on the client | TanStack Query, generated OpenAPI SDK, Zod |
| API | Go, Gin, Huma v2 |
| ORM | GORM |
| Database | PostgreSQL 16 (citext, pgcrypto) |
| Media | MinIO (S3 API), processed in-process with libvips |
| Auth | JWT, bcrypt, cookie |
| Live updates | SSE (/feed/stream, /notifications/stream) |
| Deploy | Docker Compose: web, api, postgres, minio |
Data model
The schema is source/schema.sql. The API does not create tables when it starts. Apply that file with psql.
Clients do not see numeric row ids. A user is named by username (lowercase, 3-16 characters, [A-Za-z0-9_]). A post is named by a 12-character public id. Internal bigserial ids stay on the server for joins and cursors.
| Table | Role |
|---|---|
users | Account and profile. Soft delete. Email and username are citext. |
retired_usernames | Usernames from closed accounts. Never reused. |
posts | Body (max 500), optional reply parent, soft delete and edited flags. |
post_media | Up to 4 images (including GIF) or 1 video, ordered by position. |
reactions | One emoji reaction per user per post. |
shares | Outbound share. Rows are not updated or removed. |
follows | Follower / followee pair. |
hashtags / post_hashtags | Tags parsed from the body. |
notifications | Reaction, reply, follow, mention. |
reports | Post or profile. An admin resolves them. |
Diagram: wiki ERD.
If someone closes an account, the email is released and the username is retired. That author's posts become tombstones: no author and no body. Mentions written before the close cannot land on a new person who picks the same name.
API
The API process serves OpenAPI. Routes are grouped like this:
| Area | Routes |
|---|---|
| Health | GET /health (200 if Postgres answers) |
| Auth | /auth/register, /auth/login, /auth/logout, /auth/me, email / password / close account |
| Users | /users/{username}, posts, replies, followers, following, friends, follow, report, /me, /suggestions |
| Posts | /feed, /posts, /posts/{id}, thread, reaction, reactions, share, report |
| Media | POST /media (upload first, then attach ids on the post) |
| Search | /search |
| Notifications | list, unread count, mark read, /notifications/stream |
| Feed live | /feed/stream |
| Admin | profiles, close account, reports |
Feed sort query: recent, trending, top, funniest, saddest, maddest, shocking.
Auth
Sign up needs display name, username, email, and a password (8 to 72 characters; bcrypt). Log in accepts email or username. Username is stored lowercase.
The JWT secret (EMOTIAL_AUTH_JWT_SECRET) has to be at least 32 characters. The cookie is HttpOnly. In production, Secure is on.
/auth/me is how the web app decides Guest vs User. If that response fails to parse, the app treats the visitor as a Guest.
Media
Upload is its own request. The composer uploads in the background. Creating a post only sends media ids.
Images (including GIF, HEIC, and AVIF) are normalized with libvips in the API process. Videos are stored as uploaded. Duration is recorded.
Objects live in the emotial bucket. Keys look like prefix/date/random so they are hard to guess. Browsers read public_url/bucket/key (path-style). Production uses a CDN origin (cdn.emotial.app).
If MinIO env is unset, the API still starts. Uploads are off.
Web app
App Router. A guest can open /, /explore, and /profile/{username}. Notifications and settings need a session.
The generated SDK is the HTTP client for documented routes. The cache holds UI shapes. Mutations update the cache first, then sync with the server.
Authored text is limited to Latin letters, everyday punctuation, and emoji. Other scripts are rejected on write so layout bombs do not get stored.
Theme and accent hue are client preferences.
Deployment
See deploy instructions.
| Service | Port | Notes |
|---|---|---|
| web | 3000 | NEXT_PUBLIC_API_BASE_URL is set when the image is built |
| api | 8080 | Env config (EMOTIAL_*). Optional config.toml |
| postgres | 5432 | Apply schema.sql once |
| minio | 9000 / 9001 | API creates the bucket when EMOTIAL_MEDIA_ENSURE_BUCKET=true |
Production is the same four containers on Slater's server, with public origins, a real JWT secret, secure cookies, and a CDN in front of MinIO.
Not in this build
These were in the original proposal and did not ship:
- Password reset email / Resend
- Google OAuth
- Socket.io
- Bot accounts / a public developer bot API (the HTTP API is for the app)
- Follower count badges