7.9 KiB
7.9 KiB
TicketHub - Developer Guide
Overview
TicketHub is a lightweight, enterprise-grade open-source ticket and issue tracking system. Built with a modern React frontend and Python FastAPI backend.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ TicketHub │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Frontend (React) │ │
│ │ Dashboard │ Tickets │ Board │ Projects │ Settings │ │
│ └─────────────────────────┬─────────────────────────────┘ │
│ │ │
│ REST API │
│ │ │
│ ┌─────────────────────────▼─────────────────────────────┐ │
│ │ Backend (FastAPI) │ │
│ │ /api/projects │ /api/tickets │ /api/webhooks │ │
│ └─────────────────────────┬─────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────▼─────────────────────────────┐ │
│ │ SQLite Database │ │
│ └───────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Tech Stack
Frontend
- React 18 - UI library
- TypeScript - Type safety
- TailwindCSS - Styling
- React Router - Navigation
- React Query - Data fetching
- Vite - Build tool
Backend
- Python 3.11 - Language
- FastAPI - Web framework
- SQLite - Database (dev)
- PostgreSQL - Database (prod)
Project Structure
tickethub/
├── backend/
│ └── app/
│ └── main.py # FastAPI application
├── frontend/
│ ├── src/
│ │ ├── components/
│ │ │ ├── ui/ # Reusable UI components
│ │ │ └── Layout.tsx # Main layout
│ │ ├── pages/ # Route pages
│ │ ├── services/
│ │ │ └── api.ts # API client
│ │ ├── App.tsx # Router setup
│ │ └── main.tsx # Entry point
│ ├── index.html
│ ├── package.json
│ ├── tailwind.config.js
│ └── vite.config.ts
├── docs/
└── README.md
Frontend Development
Component Library
TicketHub includes a custom component library:
// Available components
import {
Card,
Button,
Input,
Select,
Badge,
Modal,
Tabs, TabsList, TabsTrigger, TabsContent,
Table, TableHeader, TableHead, TableBody, TableRow, TableCell,
Avatar
} from '../components/ui'
Adding a New Page
- Create component in
src/pages/:
// src/pages/MyPage.tsx
import { Card, Button } from '../components/ui'
export default function MyPage() {
return (
<div className="p-6">
<h1 className="text-2xl font-bold">My Page</h1>
<Card>
<p>Content here</p>
</Card>
</div>
)
}
- Add route in
App.tsx:
import MyPage from './pages/MyPage'
// Inside Routes
<Route path="mypage" element={<MyPage />} />
- Add to sidebar in
Layout.tsx
API Integration
Use React Query for data fetching:
import { useQuery, useMutation } from '@tanstack/react-query'
import { ticketsApi } from '../services/api'
function MyComponent() {
// Fetch data
const { data: tickets, isLoading } = useQuery({
queryKey: ['tickets'],
queryFn: () => ticketsApi.list()
})
// Mutate data
const createMutation = useMutation({
mutationFn: ticketsApi.create,
onSuccess: () => queryClient.invalidateQueries(['tickets'])
})
}
Backend Development
API Structure
# Models
class Ticket(BaseModel):
id: int
key: str
project_id: int
title: str
description: str
status: Literal['open', 'in_progress', 'resolved', 'closed']
priority: Literal['low', 'medium', 'high', 'critical']
assignee: Optional[str]
reporter: Optional[str]
created_at: datetime
updated_at: datetime
# Endpoints
GET /api/projects
POST /api/projects
GET /api/projects/{id}
PATCH /api/projects/{id}
DELETE /api/projects/{id}
GET /api/tickets
POST /api/tickets
GET /api/tickets/{id}
PATCH /api/tickets/{id}
DELETE /api/tickets/{id}
GET /api/tickets/{id}/comments
POST /api/tickets/{id}/comments
Adding a New Endpoint
@app.post("/api/myresource")
async def create_myresource(data: MyModel):
# Validate
# Save to database
# Return response
return {"id": new_id, **data.dict()}
Webhook System
TicketHub sends webhooks on ticket events:
async def send_webhook(project_id: int, event: str, data: dict):
project = await get_project(project_id)
if project.webhook_url:
payload = {
"event": event, # ticket.created, ticket.updated, etc.
"timestamp": datetime.utcnow().isoformat(),
"data": data
}
await httpx.post(project.webhook_url, json=payload)
Running Locally
Backend
cd backend
pip install -r requirements.txt
uvicorn app.main:app --reload --port 8001
Frontend
cd frontend
npm install
npm run dev
Full Stack (Development)
# Terminal 1: Backend
cd backend && uvicorn app.main:app --reload --port 8001
# Terminal 2: Frontend (proxies /api to backend)
cd frontend && npm run dev
Building for Production
Frontend Build
cd frontend
npm run build
# Output: dist/
Docker Deploy
version: '3.8'
services:
api:
image: python:3.11-slim
command: uvicorn app.main:app --host 0.0.0.0 --port 8000
web:
image: nginx:alpine
volumes:
- ./frontend/dist:/usr/share/nginx/html
Testing
Backend Tests
cd backend
pytest tests/
Frontend Tests
cd frontend
npm test
API Testing
# Create project
curl -X POST http://localhost:8001/api/projects \
-H "Content-Type: application/json" \
-d '{"name": "Test Project", "key": "TEST"}'
# Create ticket
curl -X POST http://localhost:8001/api/tickets \
-H "Content-Type: application/json" \
-d '{
"project_id": 1,
"title": "Test ticket",
"description": "Test description",
"priority": "medium"
}'
Contributing
- Fork the repository
- Create feature branch:
git checkout -b feature/my-feature - Make changes
- Run tests
- Submit pull request
License
MIT License - StartData 2026