Skip to content
Merged

Test #61

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
111 changes: 111 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,112 @@
# ChatAPI
ChatAPI is a robust AI chatbot application designed to deliver seamless and customizable interactions with AI models. Developed using Node.js, Express, and Handlebars, it supports multiple AI providers and offers an intuitive interface for managing chat histories, settings, and more.

## Key Features

- **Multi-Model Compatibility**: Supports AI models like Gemini, NVIDIA, and Mallow.
- **Customizable User Experience**: Adjust themes, font sizes, temperature, and model preferences.
- **Chat History Management**: Save, retrieve, and delete chat histories effortlessly.
- **Modern Interface**: Clean, responsive design with features like skeleton loading, copy-to-clipboard for code blocks, and styled tables.
- **Admin Dashboard**: Manage AI model configurations and quotas with ease.
- **Robust Error Handling**: Comprehensive error management for API requests and database operations.

## Technology Stack

- **Backend**: Node.js, Express.js
- **Database**: PostgreSQL
- **AI Integration**: Google Gemini API
- **Authentication**: Custom-built authentication system
- **Frontend**: Handlebars templating engine
- **Styling**: Custom CSS
- **Performance Enhancements**: Compression and minification enabled

## Prerequisites

- Node.js (v14 or higher)
- PostgreSQL database
- Google Cloud Platform account (for Gemini API)
- Properly configured environment variables

## Environment Variables

Create a `.env` file in the root directory with the following variables:

```env
NEON_POSTGRES=your_postgres_connection_string
Main_SECRET_TOKEN=your_secret_token
session_seceret_key=your_session_secret
IsDeployed=true_or_false
UserCredentialTable=your_credentials_table_name
RECAPTCHA_SECRET_KEY=your_recaptcha_secret
GEMINI_API_KEY=your_gemini_api_key
GOOGLE_APPLICATION_CREDENTIALS=path_to_google_credentials
```

## Installation Guide

1. Clone the repository:
```bash
git clone https://github.com/MIbnEKhalid/ChatAPI
cd ChatAPI
```

2. Install dependencies:
```bash
npm install
```

3. Set up the database:
- Update the connection strings in your `.env` file.
- [`routes/pool.js`](routes/pool.js) will automatically create tables in db from [`model/db.sql`](model/db.sql)

4. Start the development server:
```bash
npm run dev
```

The application will be accessible at `http://localhost:3030`.

## API Endpoints

### Chat Endpoints
- `POST /api/chat` - Interact with the AI.
- `GET /api/chat/history` - Retrieve chat history.
- `GET /api/chat/history/:id` - Fetch specific chat history.
- `POST /api/chat/history` - Save chat history.
- `DELETE /api/chat/history/:id` - Remove chat history.

### User Settings
- `GET /api/settings` - Retrieve user settings.
- `POST /api/settings` - Update user settings.

### Authentication
- `POST /api/auth/login` - Log in a user.
- `POST /api/auth/logout` - Log out a user.
- `GET /api/auth/check` - Verify authentication status.

## Project Structure

```
├── routes/ # API routes and controllers
├── views/ # Handlebars templates
├── public/ # Static assets
├── documentation/ # Project documentation
├── index.js # Main application file
└── package.json # Project dependencies
```

## Contribution Guidelines

1. Fork the repository.
2. Create a feature branch (`git checkout -b feature/AmazingFeature`).
3. Commit your changes (`git commit -m 'Add some AmazingFeature'`).
4. Push to the branch (`git push origin feature/AmazingFeature`).
5. Open a Pull Request.

## License

This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.

## Authors

Developed by Muhammad Bin Khalid (MIbnEKhalid) and Maaz Waheed (42Wor) at mbktechstudio.
50 changes: 0 additions & 50 deletions documentation/database.md

This file was deleted.

65 changes: 65 additions & 0 deletions model/db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE IF NOT EXISTS ai_history_chatapi (
id SERIAL PRIMARY KEY,
conversation_id UUID NOT NULL DEFAULT uuid_generate_v4(),
conversation_history JSONB,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMPTZ,
temperature FLOAT DEFAULT 1.0,
username TEXT
);
CREATE INDEX IF NOT EXISTS idx_ai_history_chatapi_username ON ai_history_chatapi(username);
CREATE INDEX IF NOT EXISTS idx_ai_history_chatapi_id ON ai_history_chatapi(id);
CREATE INDEX IF NOT EXISTS idx_ai_history_chatapi_created_at ON ai_history_chatapi(created_at);
CREATE INDEX IF NOT EXISTS idx_ai_history_chatapi_conversation_id ON ai_history_chatapi(conversation_id);
CREATE INDEX IF NOT EXISTS idx_ai_history_chatapi_conversation_history ON ai_history_chatapi USING gin (conversation_history);

UPDATE ai_history_chatapi
SET updated_at = created_at
WHERE updated_at IS NULL;

CREATE TABLE IF NOT EXISTS user_settings_chatapi (
id SERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
theme VARCHAR(20) DEFAULT 'dark',
font_size INTEGER DEFAULT 16,
ai_model VARCHAR(50) DEFAULT 'default',
temperature FLOAT DEFAULT 1.0,
daily_message_limit INTEGER DEFAULT 100,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_user_settings_chatapi_username ON user_settings_chatapi(username);

CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

DO $$
BEGIN
IF NOT EXISTS (
SELECT 1
FROM pg_trigger
WHERE tgname = 'update_user_settings_chatapi_updated_at'
) THEN
CREATE TRIGGER update_user_settings_chatapi_updated_at
BEFORE UPDATE ON user_settings_chatapi
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
END IF;
END;
$$;

CREATE TABLE IF NOT EXISTS user_message_logs_chatapi (
id SERIAL PRIMARY KEY,
username VARCHAR(255) NOT NULL,
message_count INTEGER DEFAULT 0,
date DATE DEFAULT CURRENT_DATE,
CONSTRAINT unique_user_date UNIQUE (username, date)
);
CREATE INDEX IF NOT EXISTS idx_user_message_logs_chatapi_username_date ON user_message_logs_chatapi(username, date);
8 changes: 4 additions & 4 deletions routes/checkMessageLimit.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const checkMessageLimit = async (req, res, next) => {
if (!userSettings) {
console.log(`[checkMessageLimit] Fetching settings for user: ${username}`);
const settingsQuery = await pool.query(
`SELECT daily_message_limit FROM user_settings WHERE username = $1`,
`SELECT daily_message_limit FROM user_settings_chatapi WHERE username = $1`,
[username]
);

Expand All @@ -55,10 +55,10 @@ export const checkMessageLimit = async (req, res, next) => {

// Check message count with a single query using upsert approach
const messageCountResult = await pool.query(
`INSERT INTO user_message_logs (username, date, message_count)
`INSERT INTO user_message_logs_chatapi (username, date, message_count)
VALUES ($1, $2, 1)
ON CONFLICT (username, date)
DO UPDATE SET message_count = user_message_logs.message_count + 1
DO UPDATE SET message_count = user_message_logs_chatapi.message_count + 1
RETURNING message_count`,
[username, dateString]
);
Expand All @@ -70,7 +70,7 @@ export const checkMessageLimit = async (req, res, next) => {

// Rollback the increment since they're over limit
await pool.query(
`UPDATE user_message_logs
`UPDATE user_message_logs_chatapi
SET message_count = message_count - 1
WHERE username = $1 AND date = $2`,
[username, dateString]
Expand Down
Loading