Initial commit

This commit is contained in:
2026-03-25 11:37:46 -04:00
commit dfdbb54875
41 changed files with 5079 additions and 0 deletions
+632
View File
@@ -0,0 +1,632 @@
# TechDesk — IT Ticket System
## Complete Deployment & Implementation Guide
---
## Table of Contents
1. [Project Structure](#1-project-structure)
2. [Prerequisites](#2-prerequisites)
3. [Server Setup](#3-server-setup)
4. [MySQL Database Setup](#4-mysql-database-setup)
5. [Application Deployment](#5-application-deployment)
6. [Gunicorn Configuration](#6-gunicorn-configuration)
7. [Systemd Service](#7-systemd-service)
8. [Nginx Configuration](#8-nginx-configuration)
9. [SSL Certificate](#9-ssl-certificate)
10. [First Login & Admin Setup](#10-first-login--admin-setup)
11. [AI Chatbot Configuration](#11-ai-chatbot-configuration)
12. [Email Configuration](#12-email-configuration)
13. [Code Change Map](#13-code-change-map)
14. [Features Overview](#14-features-overview)
15. [Maintenance & Operations](#15-maintenance--operations)
---
## 1. Project Structure
```
it-ticket-system/
├── run.py ← Flask entry point
├── gunicorn.conf.py ← Gunicorn worker config
├── it-ticket-system.service ← Systemd unit file
├── nginx.conf ← Nginx site config
├── setup_db.sql ← MySQL DB + user creation
├── requirements.txt ← Python dependencies
├── .env.example ← Environment variable template
├── config/
│ └── config.py ← Flask config classes (Dev/Prod)
├── app/
│ ├── __init__.py ← App factory, extension init, seed admin
│ ├── models.py ← All SQLAlchemy models
│ ├── routes/
│ │ ├── __init__.py
│ │ ├── auth.py ← Login, register, logout, profile
│ │ ├── tickets.py ← Ticket CRUD, comments, attachments
│ │ ├── admin.py ← IT/admin management views
│ │ ├── api.py ← JSON API + WebSocket events
│ │ └── chatbot.py ← AI assistant endpoint
│ ├── services/
│ │ ├── __init__.py
│ │ ├── notification_service.py ← Email + in-app + WebSocket notifications
│ │ └── log_service.py ← Activity log + ticket history helpers
│ └── templates/
│ ├── base.html ← Sidebar, topbar, chat widget, JS
│ ├── auth/
│ │ ├── login.html
│ │ ├── register.html
│ │ └── profile.html
│ ├── tickets/
│ │ ├── dashboard_employee.html
│ │ ├── dashboard_it.html
│ │ ├── create.html
│ │ ├── list.html
│ │ ├── detail.html
│ │ ├── notifications.html
│ │ ├── knowledge_base.html
│ │ └── kb_article.html
│ └── admin/
│ ├── index.html
│ ├── tickets.html
│ ├── users.html
│ ├── edit_user.html
│ ├── kb_list.html
│ ├── kb_edit.html
│ └── activity_logs.html
└── logs/ ← Created automatically at runtime
```
---
## 2. Prerequisites
On your **Ubuntu 22.04** server, ensure the following are installed:
```bash
# Update system
sudo apt update && sudo apt upgrade -y
# Python 3.10+, pip, venv
sudo apt install -y python3 python3-pip python3-venv python3-dev
# MySQL Server
sudo apt install -y mysql-server libmysqlclient-dev
# Nginx
sudo apt install -y nginx
# Certbot (Let's Encrypt SSL)
sudo apt install -y certbot python3-certbot-nginx
# Build tools (needed for some pip packages)
sudo apt install -y build-essential libssl-dev libffi-dev
# (Optional) Git for deployment
sudo apt install -y git
```
---
## 3. Server Setup
### 3.1 Create Application User & Directory
```bash
# Create a dedicated system user
sudo useradd --system --no-create-home --shell /bin/false it-tickets
# Create application directory
sudo mkdir -p /var/www/it-ticket-system
sudo chown it-tickets:www-data /var/www/it-ticket-system
sudo chmod 755 /var/www/it-ticket-system
```
### 3.2 Deploy Application Files
```bash
# Option A: Clone from your Git repository
sudo -u it-tickets git clone https://your-repo-url.git /var/www/it-ticket-system
# Option B: Upload manually via scp
scp -r ./it-ticket-system/* user@your-server:/var/www/it-ticket-system/
```
### 3.3 Create Python Virtual Environment
```bash
cd /var/www/it-ticket-system
sudo -u it-tickets python3 -m venv venv
sudo -u it-tickets venv/bin/pip install --upgrade pip
sudo -u it-tickets venv/bin/pip install -r requirements.txt
```
### 3.4 Create Upload & Log Directories
```bash
sudo -u it-tickets mkdir -p /var/www/it-ticket-system/app/static/uploads
sudo -u it-tickets mkdir -p /var/www/it-ticket-system/logs
# Ensure www-data (nginx) can read uploads
sudo chown -R it-tickets:www-data /var/www/it-ticket-system/app/static/uploads
sudo chmod -R 775 /var/www/it-ticket-system/app/static/uploads
```
---
## 4. MySQL Database Setup
### 4.1 Secure MySQL Installation
```bash
sudo mysql_secure_installation
# Follow prompts: set root password, remove anonymous users,
# disallow remote root login, remove test database.
```
### 4.2 Create Database and User
```bash
# Run the provided SQL setup script
sudo mysql -u root -p < /var/www/it-ticket-system/setup_db.sql
# Or manually:
sudo mysql -u root -p <<'EOF'
CREATE DATABASE IF NOT EXISTS it_tickets CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER IF NOT EXISTS 'it_tickets_user'@'localhost' IDENTIFIED BY 'YOUR_SECURE_PASSWORD';
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, REFERENCES
ON it_tickets.* TO 'it_tickets_user'@'localhost';
FLUSH PRIVILEGES;
EOF
```
### 4.3 Verify Connection
```bash
mysql -u it_tickets_user -p it_tickets
# Should connect without errors. Type \q to exit.
```
---
## 5. Application Deployment
### 5.1 Configure Environment Variables
```bash
# Copy the example env file
sudo -u it-tickets cp /var/www/it-ticket-system/.env.example /var/www/it-ticket-system/.env
# Edit with your actual values
sudo nano /var/www/it-ticket-system/.env
```
**Critical values to change in `.env`:**
```ini
# Generate a strong secret key:
# python3 -c "import secrets; print(secrets.token_hex(32))"
SECRET_KEY=your-generated-secret-key
# Database — match what you set in setup_db.sql
DB_PASSWORD=YOUR_SECURE_PASSWORD
# Mail — your SMTP server credentials
MAIL_SERVER=smtp.yourdomain.com
MAIL_USERNAME=ittickets@yourdomain.com
MAIL_PASSWORD=your-email-password
IT_DEPT_EMAIL=it-department@yourdomain.com
# Public URL of your app
APP_BASE_URL=https://tickets.yourdomain.com
# Anthropic API key for AI chatbot
ANTHROPIC_API_KEY=sk-ant-...
# Change default admin password
ADMIN_EMAIL=admin@yourdomain.com
ADMIN_PASSWORD=YourStrongAdminPassword!
```
### 5.2 Initialize the Database
The application automatically creates all tables and seeds the admin user on first startup. You can also trigger it manually:
```bash
cd /var/www/it-ticket-system
sudo -u it-tickets venv/bin/python -c "
from app import create_app, db
app = create_app('production')
with app.app_context():
db.create_all()
print('Database tables created successfully.')
"
```
### 5.3 Set File Permissions
```bash
# Application files: readable by the app user
sudo find /var/www/it-ticket-system -type f -exec chmod 644 {} \;
sudo find /var/www/it-ticket-system -type d -exec chmod 755 {} \;
sudo chmod 600 /var/www/it-ticket-system/.env
sudo chown it-tickets:it-tickets /var/www/it-ticket-system/.env
# Virtual environment executables
sudo chmod +x /var/www/it-ticket-system/venv/bin/gunicorn
sudo chmod +x /var/www/it-ticket-system/venv/bin/python
```
---
## 6. Gunicorn Configuration
The `gunicorn.conf.py` file at the project root controls the WSGI server.
**Key settings explained:**
| Setting | Value | Reason |
|---|---|---|
| `worker_class` | `eventlet` | Required for Flask-SocketIO WebSocket support |
| `workers` | `1` | eventlet mandates a single worker |
| `worker_connections` | `1000` | Max concurrent connections per worker |
| `timeout` | `120` | Seconds before killing an unresponsive worker |
| `bind` | `127.0.0.1:5000` | Internal only — nginx proxies publicly |
**Test Gunicorn manually before enabling the service:**
```bash
cd /var/www/it-ticket-system
sudo -u it-tickets venv/bin/gunicorn --config gunicorn.conf.py run:app
# You should see: [INFO] Listening at: http://127.0.0.1:5000
# Press Ctrl+C to stop.
```
---
## 7. Systemd Service
### 7.1 Install the Service
```bash
# Copy unit file to systemd
sudo cp /var/www/it-ticket-system/it-ticket-system.service /etc/systemd/system/
# Edit to confirm paths and user match your setup
sudo nano /etc/systemd/system/it-ticket-system.service
```
**Update these lines in the service file if needed:**
```ini
User=it-tickets
Group=www-data
WorkingDirectory=/var/www/it-ticket-system
EnvironmentFile=/var/www/it-ticket-system/.env
ExecStart=/var/www/it-ticket-system/venv/bin/gunicorn \
--config gunicorn.conf.py \
run:app
```
### 7.2 Enable and Start the Service
```bash
sudo systemctl daemon-reload
sudo systemctl enable it-ticket-system
sudo systemctl start it-ticket-system
# Verify it is running
sudo systemctl status it-ticket-system
```
### 7.3 Useful Service Commands
```bash
# View live logs
sudo journalctl -u it-ticket-system -f
# Restart after code changes
sudo systemctl restart it-ticket-system
# Stop the service
sudo systemctl stop it-ticket-system
```
---
## 8. Nginx Configuration
### 8.1 Install Site Configuration
```bash
# Copy nginx config
sudo cp /var/www/it-ticket-system/nginx.conf /etc/nginx/sites-available/it-ticket-system
# Edit: replace tickets.yourdomain.com with your actual domain
sudo nano /etc/nginx/sites-available/it-ticket-system
# Enable the site
sudo ln -s /etc/nginx/sites-available/it-ticket-system /etc/nginx/sites-enabled/
# Remove default nginx site (optional)
sudo rm -f /etc/nginx/sites-enabled/default
# Test configuration syntax
sudo nginx -t
# Reload nginx
sudo systemctl reload nginx
```
### 8.2 Nginx Tuning (Optional)
Add to `/etc/nginx/nginx.conf` inside the `http {}` block:
```nginx
# Increase for large file uploads
client_max_body_size 20M;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types text/plain text/css application/json application/javascript text/xml;
# Rate limiting
limit_req_zone $binary_remote_addr zone=app:10m rate=30r/m;
```
---
## 9. SSL Certificate
```bash
# Obtain Let's Encrypt certificate
sudo certbot --nginx -d tickets.yourdomain.com
# Certbot will automatically update your nginx config with SSL settings.
# Verify auto-renewal:
sudo certbot renew --dry-run
# The nginx.conf provided already has the SSL block commented out.
# After certbot runs, it will populate the ssl_certificate paths automatically.
```
---
## 10. First Login & Admin Setup
1. Open your browser: `https://tickets.yourdomain.com`
2. Log in with the credentials you set in `.env`:
- **Email:** `admin@yourdomain.com`
- **Password:** `YourStrongAdminPassword!`
3. **Change the admin password immediately** via Profile → Change Password.
4. Navigate to **Admin → Users** to create IT Staff accounts.
5. Set their role to `it_staff` or `admin`.
### Default Roles
| Role | Capabilities |
|---|---|
| `employee` | Create tickets, add comments, view own tickets, use chatbot, read KB |
| `it_staff` | All employee permissions + view/update all tickets, assign tickets, internal notes, manage KB |
| `admin` | All IT staff permissions + manage users, view full activity logs, deactivate accounts |
---
## 11. AI Chatbot Configuration
The chatbot uses the **Anthropic Claude API** (`claude-sonnet-4-20250514`).
1. Obtain an API key from [console.anthropic.com](https://console.anthropic.com)
2. Add to `.env`:
```ini
ANTHROPIC_API_KEY=sk-ant-api03-...
```
3. Restart the service: `sudo systemctl restart it-ticket-system`
**Chatbot capabilities:**
- Conversationally gathers issue details from employees
- Automatically creates tickets with appropriate category and priority
- Notifies IT staff immediately upon ticket creation
- Answers general IT questions without creating tickets
- Detects critical/urgent language and escalates priority accordingly
If `ANTHROPIC_API_KEY` is not set, the chatbot gracefully informs users to contact IT directly — **the rest of the application continues to function normally.**
---
## 12. Email Configuration
### Gmail / Google Workspace
```ini
MAIL_SERVER=smtp.gmail.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=ittickets@yourdomain.com
MAIL_PASSWORD=your-app-password # Use App Password, not account password
```
### Microsoft 365 / Outlook
```ini
MAIL_SERVER=smtp.office365.com
MAIL_PORT=587
MAIL_USE_TLS=True
MAIL_USERNAME=ittickets@yourdomain.com
MAIL_PASSWORD=your-password
```
### Local Postfix (no external relay)
```ini
MAIL_SERVER=localhost
MAIL_PORT=25
MAIL_USE_TLS=False
MAIL_USERNAME=
MAIL_PASSWORD=
```
**Email notifications are sent for:**
- New ticket created → IT Department email + all IT staff (in-app)
- Ticket status changed → Ticket creator
- Ticket assigned → Assigned IT staff member
- New comment added → Ticket creator + assignee
If email fails (wrong credentials, network issue), errors are **logged silently** — the ticket operation still succeeds.
---
## 13. Code Change Map
This section documents every file and what was added/changed, as a reference for future modifications.
### New Files (All files are new — this is a greenfield application)
| File | Purpose | Key Functions/Routes |
|---|---|---|
| `run.py` | Entry point | Starts Flask + SocketIO |
| `config/config.py` | Environment config | `Config`, `DevelopmentConfig`, `ProductionConfig` |
| `app/__init__.py` | App factory | `create_app()`, `_seed_admin()` |
| `app/models.py` | Database models | `User`, `Ticket`, `Comment`, `Attachment`, `Notification`, `TicketHistory`, `ActivityLog`, `KnowledgeBase` |
| `app/routes/auth.py` | Authentication | `GET/POST /auth/login`, `GET/POST /auth/register`, `GET /auth/logout`, `GET/POST /auth/profile` |
| `app/routes/tickets.py` | Ticket management | `GET/POST /tickets/new`, `GET /tickets`, `GET/POST /tickets/<id>`, `POST /tickets/<id>/update`, `POST /comments/<id>/delete`, `GET /attachments/<id>`, `GET/POST /notifications`, `GET /kb`, `GET /kb/<id>` |
| `app/routes/admin.py` | Admin/IT views | `GET /admin/`, `GET /admin/tickets`, `GET /admin/users`, `GET/POST /admin/users/<id>/edit`, `POST /admin/users/<id>/delete`, KB CRUD, `GET /admin/logs` |
| `app/routes/api.py` | JSON API + WebSocket | `GET /api/notifications/unread-count`, `POST /api/notifications/<id>/read`, `POST /api/notifications/mark-all-read`, `GET /api/stats/tickets`, Socket events: `connect`, `disconnect`, `join_ticket`, `leave_ticket` |
| `app/routes/chatbot.py` | AI assistant | `POST /chatbot/message` |
| `app/services/notification_service.py` | Notification delivery | `create_notification()`, `send_email()`, `notify_new_ticket()`, `notify_status_change()`, `notify_comment_added()`, `notify_assignment()` |
| `app/services/log_service.py` | Audit logging | `log_action()`, `log_ticket_history()` |
| `gunicorn.conf.py` | WSGI server config | eventlet worker, bind address, log paths |
| `it-ticket-system.service` | Systemd unit | Auto-start, restart-on-failure |
| `nginx.conf` | Reverse proxy | SSL termination, WebSocket upgrade, static file serving |
| `setup_db.sql` | DB initialisation | Creates database, user, grants |
### Where Logging (`log_action`) Is Called
| Event | File | Function | Log Action String |
|---|---|---|---|
| User login | `auth.py` | `login()` | `user_login` |
| User registration | `auth.py` | `register()` | `user_register` |
| User logout | `auth.py` | `logout()` | `user_logout` |
| Profile update | `auth.py` | `profile()` | `user_profile_update` |
| Ticket created | `tickets.py` | `create_ticket()` | `ticket_create` |
| Ticket updated | `tickets.py` | `update_ticket()` | `ticket_update` |
| Comment created | `tickets.py` | `ticket_detail()` | `comment_create` |
| Comment deleted | `tickets.py` | `delete_comment()` | `comment_delete` |
| Ticket created via chatbot | `chatbot.py` | `chat()` | `ticket_create_chatbot` |
| Admin edits user | `admin.py` | `edit_user()` | `admin_user_edit` |
| Admin deactivates user | `admin.py` | `delete_user()` | `admin_user_deactivate` |
| KB article created | `admin.py` | `kb_new()` | `kb_create` |
| KB article edited | `admin.py` | `kb_edit()` | `kb_edit` |
| KB article deleted | `admin.py` | `kb_delete()` | `kb_delete` |
---
## 14. Features Overview
### Employee Features
- **Dashboard** — open/active/resolved ticket counts, recent tickets, top KB articles
- **Submit Ticket** — form with title, category, priority, location, asset tag, file attachments
- **AI Chatbot** — floating chat widget (🤖 button, bottom-right); conversationally creates tickets
- **Ticket Tracking** — full ticket detail with comment thread, change history, attachments
- **Notifications** — real-time bell (WebSocket) + notification centre page
- **Knowledge Base** — self-service articles before submitting a ticket
- **Profile** — update name/department/phone, toggle email/web notifications, change password
### IT Staff Features
- **IT Dashboard** — queue metrics (open/in-progress/pending/resolved), assigned tickets, recent activity
- **All Tickets View** — filterable by status, priority, assignment (mine/unassigned/all)
- **Ticket Update Panel** — change status, priority, assignee, due date, resolution notes, internal notes
- **Internal Notes** — IT-only comments not visible to the employee
- **Ticket History** — field-level change log on every ticket
- **Knowledge Base Management** — create, edit, publish/unpublish, delete articles
### Admin Features
- **User Management** — list all users, edit role/department/status, reset passwords, deactivate
- **Activity Log** — full audit trail of all create/update/delete actions with IP addresses
- **IT Overview** — aggregate stats across all tickets and users
### Technical Features
- **Real-time WebSocket** — notifications pushed instantly via Flask-SocketIO / eventlet
- **Email Notifications** — HTML emails for new tickets, status changes, comments, assignments
- **File Attachments** — on tickets and comments; UUID-stored filenames prevent collisions
- **Ticket Numbering** — sequential daily format: `TKT-20240315-0001`
- **Audit Trail** — every significant action persisted to `activity_logs` + `ticket_history`
- **AI Ticket Creation** — chatbot flags `ai_generated=True` on auto-created tickets
---
## 15. Maintenance & Operations
### Application Logs
```bash
# Application logs (Flask)
tail -f /var/www/it-ticket-system/logs/it_tickets.log
# Gunicorn access log
tail -f /var/www/it-ticket-system/logs/gunicorn_access.log
# Gunicorn error log
tail -f /var/www/it-ticket-system/logs/gunicorn_error.log
# Systemd journal
sudo journalctl -u it-ticket-system -f --since "1 hour ago"
# Nginx logs
sudo tail -f /var/log/nginx/it_tickets_access.log
sudo tail -f /var/log/nginx/it_tickets_error.log
```
### Deploying Code Updates
```bash
cd /var/www/it-ticket-system
# Pull latest code
sudo -u it-tickets git pull origin main
# Install any new dependencies
sudo -u it-tickets venv/bin/pip install -r requirements.txt
# Apply database migrations (if you add Flask-Migrate)
# sudo -u it-tickets venv/bin/flask db upgrade
# Restart the service
sudo systemctl restart it-ticket-system
sudo systemctl status it-ticket-system
```
### Database Backup
```bash
# Full backup
mysqldump -u it_tickets_user -p it_tickets > backup_$(date +%Y%m%d_%H%M%S).sql
# Automated daily backup via cron (add to root's crontab):
# 0 2 * * * mysqldump -u it_tickets_user -pPASSWORD it_tickets | gzip > /backups/it_tickets_$(date +\%Y\%m\%d).sql.gz
```
### Firewall Configuration
```bash
sudo ufw allow 22/tcp # SSH
sudo ufw allow 80/tcp # HTTP (redirects to HTTPS)
sudo ufw allow 443/tcp # HTTPS
sudo ufw deny 5000/tcp # Block direct Gunicorn access
sudo ufw enable
sudo ufw status
```
### Troubleshooting Quick Reference
| Symptom | Likely Cause | Fix |
|---|---|---|
| 502 Bad Gateway | Gunicorn not running | `sudo systemctl restart it-ticket-system` |
| WebSocket not connecting | nginx missing upgrade headers | Verify `/socket.io/` location block in nginx.conf |
| Emails not sending | SMTP credentials | Check `.env` MAIL_* values; test with `flask shell` |
| Chatbot not responding | Missing API key | Set `ANTHROPIC_API_KEY` in `.env` and restart |
| File uploads failing | Wrong permissions on uploads dir | `sudo chown -R it-tickets:www-data app/static/uploads` |
| DB connection error | Wrong credentials | Verify `DB_*` values in `.env` match `setup_db.sql` |
| Static files 404 | Wrong nginx alias | Check `alias` path in nginx `/static/` block |