18 KiB
18 KiB
TicketHub - Architecture Document
System Overview
TicketHub is a lightweight issue tracking system designed for simplicity and extensibility. It follows a traditional client-server architecture with a React SPA frontend and FastAPI backend.
High-Level Architecture
┌─────────────────────────────────────────────────────────────────────────────────┐
│ Client │
├─────────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ React Application │ │
│ │ │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │Dashboard │ │ Tickets │ │ Board │ │ Projects │ ... │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ React Query (Cache) │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Axios HTTP Client │ │ │
│ │ └──────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────┬────────────────────────────────────────┘
│
HTTPS/REST
│
┌────────────────────────────────────────┼────────────────────────────────────────┐
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────────┐ │
│ │ FastAPI Application │ │
│ │ │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ API Router Layer │ │ │
│ │ │ /api/projects /api/tickets /api/comments /api/webhooks │ │ │
│ │ └────────────────────────────┬────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌────────────────────────────▼────────────────────────────────────┐ │ │
│ │ │ Business Logic Layer │ │ │
│ │ │ ProjectService TicketService CommentService WebhookService │ │ │
│ │ └────────────────────────────┬────────────────────────────────────┘ │ │
│ │ │ │ │
│ │ ┌────────────────────────────▼────────────────────────────────────┐ │ │
│ │ │ Data Access Layer │ │ │
│ │ │ SQLite (dev) / PostgreSQL (prod) │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────────────┘ │
│ │
│ TicketHub Server │
└─────────────────────────────────────────────────────────────────────────────────┘
Component Details
Frontend Components
src/
├── components/
│ ├── ui/ # Reusable UI primitives
│ │ ├── Button.tsx # Button variants
│ │ ├── Card.tsx # Card container
│ │ ├── Input.tsx # Form inputs
│ │ ├── Select.tsx # Dropdowns
│ │ ├── Badge.tsx # Status/priority badges
│ │ ├── Modal.tsx # Dialog modals
│ │ ├── Table.tsx # Data tables
│ │ ├── Tabs.tsx # Tab navigation
│ │ └── Avatar.tsx # User avatars
│ └── Layout.tsx # Shell with sidebar
├── pages/
│ ├── Dashboard.tsx # Overview page
│ ├── Tickets.tsx # Ticket list
│ ├── TicketDetail.tsx # Single ticket view
│ ├── Board.tsx # Kanban board
│ ├── Projects.tsx # Project management
│ ├── Team.tsx # Team management
│ ├── Reports.tsx # Analytics
│ ├── Integrations.tsx # External integrations
│ ├── Automation.tsx # Workflow rules
│ └── Settings.tsx # Configuration
└── services/
└── api.ts # API client
Backend Structure
# Main Application (main.py)
# Models
class Project:
id: int
name: str
key: str (unique, uppercase)
description: str
webhook_url: str
created_at: datetime
class Ticket:
id: int
key: str (auto-generated: PROJECT_KEY-N)
project_id: int (FK)
title: str
description: str
status: enum('open', 'in_progress', 'resolved', 'closed')
priority: enum('low', 'medium', 'high', 'critical')
assignee: str
reporter: str
created_at: datetime
updated_at: datetime
class Comment:
id: int
ticket_id: int (FK)
author: str
content: str
created_at: datetime
Database Schema
CREATE TABLE projects (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
key TEXT UNIQUE NOT NULL,
description TEXT,
webhook_url TEXT,
ticket_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE tickets (
id INTEGER PRIMARY KEY,
key TEXT UNIQUE NOT NULL,
project_id INTEGER REFERENCES projects(id),
title TEXT NOT NULL,
description TEXT,
status TEXT DEFAULT 'open',
priority TEXT DEFAULT 'medium',
assignee TEXT,
reporter TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE comments (
id INTEGER PRIMARY KEY,
ticket_id INTEGER REFERENCES tickets(id),
author TEXT NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Indexes
CREATE INDEX idx_tickets_project ON tickets(project_id);
CREATE INDEX idx_tickets_status ON tickets(status);
CREATE INDEX idx_comments_ticket ON comments(ticket_id);
API Design
RESTful Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/projects | List all projects |
| POST | /api/projects | Create project |
| GET | /api/projects/{id} | Get project |
| PATCH | /api/projects/{id} | Update project |
| DELETE | /api/projects/{id} | Delete project |
| GET | /api/tickets | List tickets (with filters) |
| POST | /api/tickets | Create ticket |
| GET | /api/tickets/{id} | Get ticket |
| PATCH | /api/tickets/{id} | Update ticket |
| DELETE | /api/tickets/{id} | Delete ticket |
| GET | /api/tickets/{id}/comments | List comments |
| POST | /api/tickets/{id}/comments | Add comment |
Webhook System
┌─────────────┐ Event ┌─────────────┐ HTTP POST ┌──────────────┐
│ Ticket │ ──────────────►│ Webhook │ ─────────────────►│ External │
│ Created │ │ Handler │ │ System │
└─────────────┘ └─────────────┘ └──────────────┘
Events: ticket.created, ticket.updated, ticket.resolved, comment.added
Deployment Architecture
Development
┌───────────────┐ ┌───────────────┐
│ Frontend │ ──────► │ Backend │
│ Vite Dev │ proxy │ Uvicorn │
│ :5173 │ /api │ :8001 │
└───────────────┘ └───────────────┘
│
▼
┌───────────────┐
│ SQLite │
│ (file) │
└───────────────┘
Production
┌─────────────────────────────────────────────────────────────┐
│ Docker Swarm │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────┐ │
│ │ Traefik Proxy │ ◄── tickethub.startdata.com.br │
│ └────────┬────────┘ │
│ │ │
│ ├────────► /api/* ────► ┌─────────────────┐ │
│ │ │ API Service │ │
│ │ │ FastAPI │ │
│ │ └────────┬────────┘ │
│ │ │ │
│ │ ▼ │
│ │ ┌─────────────────┐ │
│ │ │ PostgreSQL │ │
│ │ └─────────────────┘ │
│ │ │
│ └────────► /* ──────► ┌─────────────────┐ │
│ │ NGINX Static │ │
│ │ (React Build) │ │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
Data Flow
Creating a Ticket
1. User fills form
└─► React state
2. Submit
└─► POST /api/tickets
└─► Validate
└─► Generate key (PROJECT-N)
└─► Insert to DB
└─► Return ticket
3. Webhook (async)
└─► If project.webhook_url
└─► POST to external URL
└─► Payload: {event, timestamp, data}
4. Update UI
└─► React Query invalidate
└─► Refetch tickets
└─► Display new ticket
Kanban Drag & Drop
1. User drags ticket
└─► onDragStart(ticketId)
2. Drop on column
└─► onDrop(status)
└─► PATCH /api/tickets/{id}
└─► {status: newStatus}
3. Optimistic update
└─► React Query mutation
└─► Update local cache
└─► Rerender board
4. Server confirms
└─► Persist change
└─► Trigger webhook
Security
Current Implementation
- No authentication (open access)
- Input validation via Pydantic
- SQL injection prevention via parameterized queries
Recommended Additions
- JWT authentication
- Role-based access control
- API rate limiting
- Audit logging
- CSRF protection
Performance
Frontend
- React Query caching (5 min stale time)
- Lazy loading for routes
- Optimistic updates for mutations
- Virtualized lists for large datasets
Backend
- Async endpoints (non-blocking I/O)
- Database connection pooling
- Pagination for list endpoints
- Indexed queries
Extensibility
Adding New Features
- New ticket fields: Add to model, migration, API, and UI
- New integrations: Add to Integrations page and webhook handler
- New automation: Add to rules engine and trigger points
Plugin System (Future)
┌─────────────────┐
│ TicketHub │
│ Core │
├─────────────────┤
│ Plugin API │
├─────────────────┤
│ ┌─────┐ ┌─────┐ │
│ │Slack│ │Email│ │
│ └─────┘ └─────┘ │
│ ┌─────┐ ┌─────┐ │
│ │Jira │ │Git │ │
│ └─────┘ └─────┘ │
└─────────────────┘
Monitoring
Health Check
GET /api/health
→ {"status": "healthy", "version": "1.0.0"}
Metrics (Future)
- Request count
- Response times
- Error rates
- Active users
Document Version: 1.0 Last Updated: February 2026 StartData Engineering