Skip to content

BarYosef212/Connectly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Social Network Application

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.

🎥 Demo Video

🚀 Features

  • 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

🛠️ Tech Stack

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

📋 Prerequisites

  • Node.js 18+ and npm
  • PostgreSQL database (cloud-hosted)
  • Cloudinary account
  • OpenAI API key
  • Docker & Docker Compose (optional)

🚀 Quick Start

Option 1: Docker (Recommended)

  1. Clone repository:

    git clone https://github.com/BarYosef212/Connectly.git
    cd Connectly
  2. Set up environment variables:

    cp .env.example .env
    cp backend/.env.example backend/.env
    cp frontend/.env.example frontend/.env

    Edit .env files with your values (database URL, Cloudinary, OpenAI keys).

  3. Run with Docker:

    docker-compose up --build
  4. Access:

Option 2: Local Development

Step 1: Clone the Repository

git clone https://github.com/BarYosef212/Connectly.git
cd Connectly

Step 2: Backend Setup

  1. Navigate to backend directory:

    cd backend
  2. Install dependencies:

    npm install

    This will install all backend dependencies including Express, Prisma, Socket.IO, etc.

  3. Set up environment variables:

    cp .env.example .env

    Open backend/.env and 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.

  4. Set up Prisma and Database:

    # Generate Prisma Client (creates the database client)
    npx prisma generate

    This command reads your prisma/schema.prisma file and generates the Prisma Client that you'll use to interact with your database.

    # Push schema to your cloud database
    npx prisma db push

    This command will:

    • Connect to your cloud database using the DATABASE_URL from .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_URL is correct
    • Check that your IP is whitelisted in your cloud database settings
    • For SSL-required databases, add ?sslmode=require to your DATABASE_URL
  5. Start the backend server:

    npm run dev

    The backend will start on http://localhost:3001. You should see:

    Server running on port 3001
    

Step 3: Frontend Setup

  1. Open a new terminal and navigate to frontend directory:

    cd frontend
  2. Install dependencies:

    npm install

    This will install all frontend dependencies including React, Vite, Tailwind CSS, etc.

  3. Set up environment variables:

    cp .env.example .env

    Open frontend/.env and set:

    VITE_API_BASE_URL=http://localhost:3001

    This tells the frontend where to find your backend API.

  4. 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.

🏗️ Architecture Overview

Backend Architecture

The backend follows a layered architecture pattern with clear separation of concerns:

Request Flow:
Client → Routes → Middleware → Controllers → Services → Database (Prisma)

Layer Breakdown:

  1. 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
  2. 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
  3. 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
  4. Services Layer (src/services/)

    • Contains all business logic
    • Interacts with database via Prisma
    • Handles data transformations
    • No direct HTTP knowledge
    • Examples: authService, postService, friendService
  5. 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
  6. 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

External Services Integration:

  • 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

Frontend Architecture

The frontend follows React best practices with component-based architecture:

Component Hierarchy:
App → Router → Pages → Components → Hooks/API

Key Components:

  1. Pages (src/pages/)

    • Top-level route components
    • Examples: Feed, Profile, Friends, Chat, Login
    • Handle page-level logic and state
  2. 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
  3. Contexts (src/contexts/)

    • AuthContext - Manages authentication state, user data, Socket.IO connection
    • Provides auth state to entire app
    • Handles login/logout and token management
  4. Hooks (src/hooks/)

    • Custom React hooks for reusable logic
    • useFriends - Friend management
    • useChat - Chat functionality
    • useFeed - Feed data fetching
    • useUserSearch - User search
    • useFriendshipStatus - Friendship status checking
  5. API Layer (src/api/)

    • Axios-based API client with interceptors
    • Automatic JWT token injection
    • Centralized error handling
    • Type-safe API functions
  6. State Management:

    • React Context API - Global auth state
    • Local State - Component-specific state with useState
    • Custom Hooks - Encapsulated stateful logic

Real-Time Communication

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

Data Flow Examples

Creating a Post:

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

Real-Time Chat:

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

Security Architecture

  • 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

Database Design

The application uses PostgreSQL with Prisma ORM for type-safe database access. The database schema consists of 7 main models with well-defined relationships.

Database Schema Diagram

Database Schema

Models Overview

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

Key Design Decisions

  • 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: Cascade to maintain referential integrity
  • Privacy Levels: Posts support three privacy levels (public, friends, private) enforced at the application layer
  • Optimization: Post model includes likeCount field to avoid counting likes on every query
  • Timestamps: All models track createdAt and most track updatedAt for audit purposes
  • Snake Case Mapping: Database columns use snake_case while Prisma models use camelCase

Relationships Summary

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)

🔧 Environment Variables

Backend (backend/.env)

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-key

Frontend (frontend/.env)

VITE_API_BASE_URL=http://localhost:3001

🔌 API Endpoints

Authentication

  • POST /api/auth/register - Register user
  • POST /api/auth/login - Login

Users

  • GET /api/users/search - Search users
  • GET /api/users/:userId - Get profile
  • PUT /api/users/profile - Update profile
  • POST /api/users/createImage - Generate AI image
  • POST /api/users/createText - Generate AI text

Friends

  • GET /api/friends - Get friends list
  • GET /api/friends/requests - Get requests
  • POST /api/friends/request - Send request
  • POST /api/friends/accept - Accept request
  • POST /api/friends/reject - Reject request
  • DELETE /api/friends/:friendId - Remove friend

Posts

  • GET /api/posts/:postId - Get post
  • POST /api/posts - Create post
  • PUT /api/posts/:postId - Update post
  • DELETE /api/posts/:postId - Delete post
  • POST /api/posts/:postId/like - Like/unlike

Feed & Comments

  • GET /api/feed - Get feed (query: page, limit)
  • GET /api/comments/post/:postId - Get comments
  • POST /api/comments - Create comment
  • PUT /api/comments/:commentId - Update comment
  • DELETE /api/comments/:commentId - Delete comment

Upload & Chat

  • POST /api/upload/image - Upload image file
  • POST /api/upload/base64 - Upload base64 image
  • GET /api/chat/conversations - Get conversations
  • GET /api/chat/messages/:conversationId - Get messages
  • POST /api/chat/messages - Send message

🔄 Socket.IO Events

Client → Server: post:created, post:updated, post:deleted, comment:created
Server → Client: post:new, post:updated, comment:new, message:new, friendRequest:new, friend:removed

🐛 Troubleshooting

Database connection errors:

  • Verify DATABASE_URL is correct
  • Check IP whitelisting in cloud database settings
  • Add ?sslmode=require if 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_URL matches backend URL
  • Check CORS configuration

Docker issues:

  • View logs: docker-compose logs -f
  • Rebuild: docker-compose up --build
  • Ensure .env files are configured

📦 Project Structure

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

📝 License

This project is created for educational purposes.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages