A full-stack real-time social network application built with React, Node.js, PostgreSQL, and Socket.IO. Features include user authentication, friend management, posts with privacy controls, real-time chat, AI-powered content generation, and image uploads via Cloudinary.
- Authentication - JWT-based user registration and login
- User Profiles - Customizable profiles with avatar uploads
- Friends System - Send/accept/reject friend requests, user search
- Posts - Create, edit, delete posts with privacy levels (Public/Friends/Private)
- AI Features - Generate images (DALL-E 3) and text (GPT-4o-mini) for posts
- Image Upload - Upload images from computer or generate with AI (Cloudinary)
- Real-Time Chat - Private messaging between friends
- Comments - Comment on friends' posts with real-time updates
- Feed - Personalized feed showing own and friends' posts
- Real-Time Updates - Live updates via Socket.IO for posts, comments, and messages
Frontend: React 18, TypeScript, Vite, Tailwind CSS, Radix UI, Socket.IO Client
Backend: Node.js, Express, TypeScript, PostgreSQL, Prisma, Socket.IO, JWT, Cloudinary, OpenAI API
- Node.js 18+ and npm
- PostgreSQL database (cloud-hosted)
- Cloudinary account
- OpenAI API key
- Docker & Docker Compose (optional)
-
Clone repository:
git clone https://github.com/BarYosef212/Connectly.git cd Connectly -
Set up environment variables:
cp .env.example .env cp backend/.env.example backend/.env cp frontend/.env.example frontend/.env
Edit
.envfiles with your values (database URL, Cloudinary, OpenAI keys). -
Run with Docker:
docker-compose up --build
-
Access:
- Frontend: http://localhost:3000
- Backend: http://localhost:3001
git clone https://github.com/BarYosef212/Connectly.git
cd Connectly-
Navigate to backend directory:
cd backend -
Install dependencies:
npm install
This will install all backend dependencies including Express, Prisma, Socket.IO, etc.
-
Set up environment variables:
cp .env.example .env
Open
backend/.envand configure the following:# Database - Use your cloud PostgreSQL connection string DATABASE_URL="postgresql://user:password@your-cloud-host:5432/database?schema=public" # JWT Secret - Use a strong random string JWT_SECRET="your-super-secret-jwt-key-change-this-in-production" # Server Configuration PORT=3001 FRONTEND_URL="http://localhost:3000" # Cloudinary - Get from https://cloudinary.com/console CLOUDINARY_CLOUD_NAME="your-cloud-name" CLOUDINARY_API_KEY="your-api-key" CLOUDINARY_API_SECRET="your-api-secret" # OpenAI - Get from https://platform.openai.com/api-keys OPENAI_API_KEY="your-openai-api-key"
Important: Replace all placeholder values with your actual credentials.
-
Set up Prisma and Database:
# Generate Prisma Client (creates the database client) npx prisma generateThis command reads your
prisma/schema.prismafile and generates the Prisma Client that you'll use to interact with your database.# Push schema to your cloud database npx prisma db pushThis command will:
- Connect to your cloud database using the
DATABASE_URLfrom.env - Create all tables, relationships, and indexes defined in your Prisma schema
- Sync your database structure with the schema file
Note: If you encounter connection errors:
- Verify your
DATABASE_URLis correct - Check that your IP is whitelisted in your cloud database settings
- For SSL-required databases, add
?sslmode=requireto yourDATABASE_URL
- Connect to your cloud database using the
-
Start the backend server:
npm run dev
The backend will start on
http://localhost:3001. You should see:Server running on port 3001
-
Open a new terminal and navigate to frontend directory:
cd frontend -
Install dependencies:
npm install
This will install all frontend dependencies including React, Vite, Tailwind CSS, etc.
-
Set up environment variables:
cp .env.example .env
Open
frontend/.envand set:VITE_API_BASE_URL=http://localhost:3001
This tells the frontend where to find your backend API.
-
Start the frontend development server:
npm run dev
The frontend will start on
http://localhost:3000. Open this URL in your browser to access the application.
The backend follows a layered architecture pattern with clear separation of concerns:
Request Flow:
Client → Routes → Middleware → Controllers → Services → Database (Prisma)
-
Routes Layer (
src/routes/)- Define API endpoints and HTTP methods
- Apply middleware (authentication, validation)
- Route requests to appropriate controllers
- Example:
/api/posts,/api/auth/login
-
Middleware Layer (
src/middleware/)- Authentication (
auth.ts) - Validates JWT tokens, extracts user ID - Validation (
validators/) - Validates request data using express-validator - Upload (
upload.ts) - Handles file uploads with Multer - Request Validation (
validateRequest.ts) - Checks validation results
- Authentication (
-
Controllers Layer (
src/controllers/)- Handle HTTP requests and responses
- Extract data from requests
- Call service layer for business logic
- Return appropriate HTTP responses
- Handle errors and status codes
-
Services Layer (
src/services/)- Contains all business logic
- Interacts with database via Prisma
- Handles data transformations
- No direct HTTP knowledge
- Examples:
authService,postService,friendService
-
Database Layer (
src/prisma.ts+prisma/schema.prisma)- Prisma ORM for type-safe database access
- Schema defines all models and relationships
- Generated Prisma Client provides database methods
-
Socket.IO Layer (
src/socket.ts)- Real-time WebSocket communication
- Handles authentication for socket connections
- Manages user rooms for targeted updates
- Emits events for posts, comments, messages, friend requests
- Cloudinary (
services/uploadService.ts) - Image storage and CDN - OpenAI API (
controllers/userController.ts) - AI image and text generation - JWT (
services/authService.ts) - Token generation and validation
The frontend follows React best practices with component-based architecture:
Component Hierarchy:
App → Router → Pages → Components → Hooks/API
-
Pages (
src/pages/)- Top-level route components
- Examples:
Feed,Profile,Friends,Chat,Login - Handle page-level logic and state
-
Components (
src/components/)- Reusable UI components
- UI Components (
components/ui/) - Base components (Button, Card, Input, etc.) - Feature Components - Domain-specific components (PostCard, CommentSection, ChatWindow)
- Layout Components - Navbar, PrivateRoute
-
Contexts (
src/contexts/)- AuthContext - Manages authentication state, user data, Socket.IO connection
- Provides auth state to entire app
- Handles login/logout and token management
-
Hooks (
src/hooks/)- Custom React hooks for reusable logic
useFriends- Friend managementuseChat- Chat functionalityuseFeed- Feed data fetchinguseUserSearch- User searchuseFriendshipStatus- Friendship status checking
-
API Layer (
src/api/)- Axios-based API client with interceptors
- Automatic JWT token injection
- Centralized error handling
- Type-safe API functions
-
State Management:
- React Context API - Global auth state
- Local State - Component-specific state with
useState - Custom Hooks - Encapsulated stateful logic
Socket.IO enables bidirectional real-time communication:
- Connection: Established on login via
AuthContext - Authentication: Socket connections authenticated with JWT
- Rooms: Users join personal rooms for targeted updates
- Events:
- Posts (create, update, delete)
- Comments (create, update, delete)
- Messages (send, receive)
- Friend requests (new, accepted, rejected)
- Friend removals
1. User submits form → CreatePost component
2. Component calls → postApi.createPost()
3. API sends → POST /api/posts (with JWT token)
4. Backend Route → posts.ts → authenticate middleware
5. Controller → postController.createPost()
6. Service → postService.createPost() → Prisma
7. Database → Insert post
8. Socket.IO → Emit 'post:new' to relevant users
9. Frontend → Receives socket event → Updates feed
1. User types message → ChatWindow component
2. Client sends HTTP POST → /messages עם { recipientId, content }
3. Backend HTTP → Validates → Saves to DB
4. Backend HTTP → Emits Socket.IO 'message:new' event to both users
5. Recipient's ChatWindow → Listens ל־'message:new' → Updates UI
- Authentication: JWT tokens stored in localStorage
- Authorization: Middleware checks user permissions
- Input Validation: Express-validator on all endpoints
- Password Security: bcrypt hashing (10 rounds)
- CORS: Configured for frontend origin only
- File Upload: Size limits and type validation
- SQL Injection: Prevented by Prisma ORM
The application uses PostgreSQL with Prisma ORM for type-safe database access. The database schema consists of 7 main models with well-defined relationships.
1. User Model
- Stores user account information
- Fields:
id(UUID),username(unique),email(unique),passwordHash,bio,avatarUrl, timestamps - Relationships:
- One-to-many with Posts
- One-to-many with Comments
- One-to-many with Likes
- Many-to-many with other Users via Friendships (bidirectional)
- One-to-many with Conversations (as user1 or user2)
- One-to-many with Messages
2. Friendship Model
- Manages friend relationships and requests
- Composite Primary Key:
(requesterId, recipientId) - Fields:
requesterId,recipientId,status("pending" | "accepted"),createdAt - Relationships:
- Many-to-one with User (requester)
- Many-to-one with User (recipient)
- Cascade delete: Deleting a user removes all their friendships
3. Post Model
- Stores user posts with privacy controls
- Fields:
id(UUID),userId,content,imageUrl,privacyLevel("public" | "friends" | "private"),likeCount, timestamps - Relationships:
- Many-to-one with User
- One-to-many with Comments
- One-to-many with Likes
- Cascade delete: Deleting a user removes all their posts
4. Comment Model
- Stores comments on posts
- Fields:
id(UUID),postId,userId,content, timestamps - Relationships:
- Many-to-one with Post
- Many-to-one with User
- Cascade delete: Deleting a post or user removes associated comments
5. Like Model
- Tracks which users liked which posts
- Composite Primary Key:
(userId, postId) - Fields:
userId,postId,createdAt - Relationships:
- Many-to-one with User
- Many-to-one with Post
- Prevents duplicate likes (enforced by composite key)
- Cascade delete: Deleting a user or post removes associated likes
6. Conversation Model
- Represents a chat conversation between two users
- Fields:
id(UUID),user1Id,user2Id, timestamps - Unique constraint:
(user1Id, user2Id)- ensures one conversation per user pair - Relationships:
- Many-to-one with User (user1)
- Many-to-one with User (user2)
- One-to-many with Messages
- Cascade delete: Deleting a user removes their conversations
7. Message Model
- Stores individual chat messages
- Fields:
id(UUID),conversationId,senderId,content,read(boolean), timestamps - Relationships:
- Many-to-one with Conversation
- Many-to-one with User (sender)
- Cascade delete: Deleting a conversation or user removes associated messages
- UUIDs for Primary Keys: All models use UUIDs instead of auto-incrementing integers for better scalability and security
- Composite Keys: Friendship and Like models use composite primary keys to prevent duplicates and enforce business rules
- Cascade Deletes: All relationships use
onDelete: Cascadeto maintain referential integrity - Privacy Levels: Posts support three privacy levels (public, friends, private) enforced at the application layer
- Optimization: Post model includes
likeCountfield to avoid counting likes on every query - Timestamps: All models track
createdAtand most trackupdatedAtfor audit purposes - Snake Case Mapping: Database columns use snake_case while Prisma models use camelCase
User ──┬── Posts (1:N)
├── Comments (1:N)
├── Likes (1:N)
├── Friendships (N:M via Friendship model)
├── Conversations (N:M via Conversation model)
└── Messages (1:N)
Post ──┬── Comments (1:N)
└── Likes (1:N)
Conversation ── Messages (1:N)
DATABASE_URL=postgresql://user:password@host:port/database?schema=public
JWT_SECRET=your-secret-key
PORT=3001
FRONTEND_URL=http://localhost:3000
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
OPENAI_API_KEY=your-openai-keyVITE_API_BASE_URL=http://localhost:3001POST /api/auth/register- Register userPOST /api/auth/login- Login
GET /api/users/search- Search usersGET /api/users/:userId- Get profilePUT /api/users/profile- Update profilePOST /api/users/createImage- Generate AI imagePOST /api/users/createText- Generate AI text
GET /api/friends- Get friends listGET /api/friends/requests- Get requestsPOST /api/friends/request- Send requestPOST /api/friends/accept- Accept requestPOST /api/friends/reject- Reject requestDELETE /api/friends/:friendId- Remove friend
GET /api/posts/:postId- Get postPOST /api/posts- Create postPUT /api/posts/:postId- Update postDELETE /api/posts/:postId- Delete postPOST /api/posts/:postId/like- Like/unlike
GET /api/feed- Get feed (query:page,limit)GET /api/comments/post/:postId- Get commentsPOST /api/comments- Create commentPUT /api/comments/:commentId- Update commentDELETE /api/comments/:commentId- Delete comment
POST /api/upload/image- Upload image filePOST /api/upload/base64- Upload base64 imageGET /api/chat/conversations- Get conversationsGET /api/chat/messages/:conversationId- Get messagesPOST /api/chat/messages- Send message
Client → Server: post:created, post:updated, post:deleted, comment:created
Server → Client: post:new, post:updated, comment:new, message:new, friendRequest:new, friend:removed
Database connection errors:
- Verify
DATABASE_URLis correct - Check IP whitelisting in cloud database settings
- Add
?sslmode=requireif SSL is required
Backend won't start:
- Check all environment variables are set
- Verify database is accessible
- Check port 3001 is available
Frontend can't connect:
- Verify backend is running on port 3001
- Check
VITE_API_BASE_URLmatches backend URL - Check CORS configuration
Docker issues:
- View logs:
docker-compose logs -f - Rebuild:
docker-compose up --build - Ensure
.envfiles are configured
social/
├── backend/
│ ├── src/
│ │ ├── controllers/ # Request handlers
│ │ ├── routes/ # API routes
│ │ ├── services/ # Business logic
│ │ ├── middleware/ # Auth, validation
│ │ └── socket.ts # Socket.IO setup
│ └── prisma/
│ └── schema.prisma # Database schema
├── frontend/
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── api/ # API client
│ │ └── hooks/ # Custom hooks
│ └── nginx.conf # Production config
└── docker-compose.yml
This project is created for educational purposes.
