Files
tickettracker/frontend/src/types.ts
T

306 lines
7.1 KiB
TypeScript

export type WorkType = "support" | "consulting";
export type BillingStatus = "billed" | "non_billable" | null;
export type PeriodType = "month" | "day";
export type TicketDetailPeriodType = PeriodType | "all";
export type UserRole = "admin" | "user";
export type AuthUser = {
id: string;
username: string;
display_name: string;
role: UserRole;
active: boolean;
};
export type AdminUser = AuthUser & {
created_at: string;
updated_at: string;
};
export type Organization = {
id: string;
zammad_id: string;
name: string;
synced_at: string;
};
export type RecurringBillingSlot = {
id?: string;
weekday: number | null;
start_time: string | null;
duration_minutes: number;
};
export type RecurringBilling = {
id: string;
user_id: string;
owner_username: string;
owner_display_name: string;
ticket_number: string;
configured_ticket_number: string | null;
organization_id: string;
organization_name: string;
activity: string;
work_type: WorkType;
recurrence_type: "weekly" | "every_n_weeks";
interval_value: number;
valid_from: string;
valid_until: string | null;
start_time: string;
active: boolean;
created_at: string;
updated_at: string;
slots: RecurringBillingSlot[];
};
export type TicketMeta = {
id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string | null;
work_type: WorkType | null;
};
export type TicketSearchResult = {
ticket_id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string | null;
work_type: WorkType | null;
latest_started_at: string;
latest_period: string;
session_count: number;
total_minutes: number;
};
export type TicketSummary = {
id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string | null;
work_type: WorkType | null;
session_count: number;
total_minutes: number;
non_billable_minutes: number;
open_minutes: number;
open_count: number;
ticket_open_count: number;
billed_count: number;
non_billable_count: number;
recurring_session_count: number;
manual_session_count: number;
requires_closure: boolean;
closed: boolean;
closed_at: string | null;
};
export type OpenSession = {
id: string;
ticket_id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string;
activity: string;
work_type: WorkType;
started_at: string;
rounded_minutes: number;
};
export type ActivityBucket = {
bucket_key: string;
session_count: number;
total_minutes: number;
};
export type PeriodOverview = {
periodType: PeriodType;
period: string;
closed: boolean;
closedAt: string | null;
canClose: boolean;
totals: {
tickets: number;
sessions: number;
minutes: number;
crmBilledMinutes: number;
nonBillableMinutes: number;
openMinutes: number;
openSessions: number;
};
tickets: TicketSummary[];
openSessions: OpenSession[];
activitySeries: ActivityBucket[];
};
export type TicketDayBilling = {
day: string;
billed_minutes: number;
};
export type TicketAvailableMonth = {
month: string;
session_count: number;
};
export type SessionEntry = {
id: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string;
activity: string;
work_type: WorkType;
started_at: string;
ended_at: string;
duration_seconds: number;
rounded_minutes: number;
billing_status: BillingStatus;
billing_updated_at: string | null;
created_at: string;
recurring_billing_id: string | null;
recurring_billing_slot_id: string | null;
recurring_occurrence_date: string | null;
};
export type TicketPeriod = {
periodType: TicketDetailPeriodType;
period: string;
closed: boolean;
closedAt: string | null;
filters?: {
month: string;
status: "all" | "open" | "billed" | "non_billable";
source: "all" | "manual" | "recurring";
};
availableMonths?: TicketAvailableMonth[];
ticket: {
id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string | null;
customer_name: string | null;
work_type: WorkType | null;
closed_at: string | null;
requires_closure: boolean;
recurring_session_count: number;
manual_session_count: number;
};
sessions: SessionEntry[];
dayBillings: TicketDayBilling[];
canClose: boolean;
openCount: number;
ticketOpenCount: number;
};
export type MonthOverview = PeriodOverview;
export type TicketMonth = TicketPeriod;
export type StatisticsDailyBucket = {
day: string;
sessions: number;
total_minutes: number;
billed_minutes: number;
non_billable_minutes: number;
open_minutes: number;
billed_sessions: number;
non_billable_sessions: number;
open_sessions: number;
crm_billed_minutes: number;
};
export type StatisticsGroup = {
organization_id?: string | null;
organization_name?: string;
work_type?: WorkType;
tickets: number;
sessions: number;
total_minutes: number;
billed_minutes: number;
non_billable_minutes: number;
open_minutes: number;
billed_sessions: number;
non_billable_sessions: number;
open_sessions: number;
crm_billed_minutes: number;
crm_delta_minutes: number;
};
export type StatisticsTicket = {
ticket_id: string;
ticket_number: string;
organization_id: string | null;
organization_name: string;
active_days: number;
sessions: number;
total_minutes: number;
billed_minutes: number;
non_billable_minutes: number;
open_minutes: number;
billed_sessions: number;
non_billable_sessions: number;
open_sessions: number;
crm_billed_minutes: number;
crm_delta_minutes: number;
};
export type StatisticsOpenSession = {
id: string;
ticket_id: string;
ticket_number: string;
organization_name: string;
activity: string;
started_at: string;
rounded_minutes: number;
};
export type StatisticsCrmDay = {
ticket_id: string;
ticket_number: string;
organization_name: string;
day: string;
tracked_minutes: number;
crm_billed_minutes: number;
delta_minutes?: number;
acknowledged?: boolean;
acknowledged_at?: string | null;
};
export type StatisticsOverview = {
periodType: "month";
period: string;
closed: boolean;
closedAt: string | null;
totals: {
tickets: number;
sessions: number;
minutes: number;
billedMinutes: number;
nonBillableMinutes: number;
openMinutes: number;
billedSessions: number;
nonBillableSessions: number;
openSessions: number;
recurringMinutes: number;
manualMinutes: number;
recurringSessions: number;
manualSessions: number;
averageSessionMinutes: number;
activeDays: number;
crmBilledMinutes: number;
crmDeltaMinutes: number;
};
dailySeries: StatisticsDailyBucket[];
organizations: StatisticsGroup[];
workTypes: StatisticsGroup[];
tickets: StatisticsTicket[];
attention: {
openSessions: StatisticsOpenSession[];
missingCrmDays: StatisticsCrmDay[];
acknowledgedMissingCrmDays: StatisticsCrmDay[];
crmMismatches: StatisticsCrmDay[];
};
};