tickethub/docs/DEVELOPER_GUIDE.md

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

  1. 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>
  )
}
  1. Add route in App.tsx:
import MyPage from './pages/MyPage'

// Inside Routes
<Route path="mypage" element={<MyPage />} />
  1. 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

  1. Fork the repository
  2. Create feature branch: git checkout -b feature/my-feature
  3. Make changes
  4. Run tests
  5. Submit pull request

License

MIT License - StartData 2026