Files
acs/frontend/src/types.ts
2026-07-20 17:29:00 +09:00

281 lines
5.6 KiB
TypeScript

export interface ApiResponse<T> {
code: number;
message: string;
data: T | null;
}
export type Role = 'ADMIN' | 'SECURITY' | 'HOST';
export interface CurrentUser {
id: number;
username: string;
fullName: string;
department?: string;
email?: string;
roles: Role[];
mustChangePassword: boolean;
}
export interface LoginRequest {
username: string;
password: string;
}
export interface ChangePasswordRequest {
oldPassword: string;
newPassword: string;
}
export interface Zone {
id: number;
code: string;
name: string;
securityLevel: number;
}
export interface PurposeCode {
id: number;
code: string;
name: string;
sortOrder: number;
active: boolean;
customAllowed: boolean;
}
export interface Watcher1Settings {
name: string;
team: string;
contact: string;
}
export interface SmsDiagnosticsResult {
provider: string;
url: string;
ok: boolean;
reachable: boolean;
httpStatus: number | null;
elapsedMs: number;
checkedAt: string;
error: string | null;
}
export interface EmailDiagnosticsResult {
host: string;
port: number;
from: string;
smtpAuth: boolean;
startTls: boolean;
usernameConfigured: boolean;
passwordConfigured: boolean;
ok: boolean;
reachable: boolean;
elapsedMs: number;
checkedAt: string;
error: string | null;
}
export interface Team {
id: number;
code: string;
name: string;
active: boolean;
defaultRoles: Role[];
}
export interface AdminUser {
id: number;
username: string;
fullName: string;
department?: string;
teamId?: number;
teamCode?: string;
teamName?: string;
email?: string;
enabled: boolean;
locked: boolean;
roles: Role[];
}
export type VisitStatus =
| 'DRAFT'
| 'PENDING'
| 'APPROVED'
| 'REJECTED'
| 'CANCELLED'
| 'EXPIRED';
export interface VisitRequestCreate {
visitorName: string;
company?: string;
contact: string;
email?: string;
vehicleNo?: string;
/** 전산실 checkboxes; each selected room yields its own request/QR. */
serverRooms?: string[];
/** Detail room (콤보박스, 기타 자유 입력) — auxiliary, no separate QR. */
roomZone?: string;
purpose: string;
purposeCode?: string;
purposeDetail?: string;
/** 작업명 — optional concrete task detail, stored separately from purpose. */
workName?: string;
/** 현장감시자2 (담당자 입력). 담당자·감시자1은 서버가 채운다. */
watcher2Name?: string;
watcher2Team?: string;
watcher2Contact?: string;
visitFrom: string; // ISO local datetime
visitTo: string;
}
export interface VisitRequestView {
id: number;
visitorName: string;
company?: string;
contact?: string;
email?: string;
vehicleNo?: string;
hostId: number;
hostName: string;
hostDepartment?: string;
zoneName?: string;
purpose: string;
purposeCode?: string;
purposeDetail?: string;
workName?: string;
controlName?: string;
controlTeam?: string;
controlContact?: string;
watcher1Name?: string;
watcher1Team?: string;
watcher1Contact?: string;
watcher2Name?: string;
watcher2Team?: string;
watcher2Contact?: string;
visitFrom: string;
visitTo: string;
status: VisitStatus;
qrToken?: string;
createdAt: string;
}
export interface PublicPass {
visitorName: string;
company?: string;
zoneName?: string;
visitFrom: string;
visitTo: string;
/** Whether the visitor is currently inside — drives the kiosk 입장/퇴장 button. */
inside: boolean;
/** Whether the visit already completed (entered & exited) today — blocks re-entry. */
completedToday: boolean;
}
export interface ExcelImportResult {
totalRows: number;
successCount: number;
errors: string[];
success: boolean;
}
export interface AdminExcelImportRow {
rowNumber: number;
status: 'CREATE' | 'UPDATE' | 'ERROR' | string;
key?: string;
summary?: string;
errors: string[];
warnings: string[];
}
export interface AdminExcelImportResult {
totalRows: number;
createCount: number;
updateCount: number;
errorCount: number;
warningCount: number;
applied: boolean;
success: boolean;
rows: AdminExcelImportRow[];
}
export interface InsideVisitor {
visitRequestId: number;
visitorName: string;
company?: string;
zoneName?: string;
hostName: string;
checkInAt: string;
}
export interface AccessRecord {
visitRequestId: number;
visitorName: string;
company?: string;
zoneName?: string;
visitFrom: string;
visitTo: string;
status?: VisitStatus;
checkInAt?: string;
checkOutAt?: string;
inside: boolean;
}
export interface AccessAction {
visitRequestId: number;
visitorName: string;
direction: 'IN' | 'OUT';
eventAt: string;
gateOpened: boolean;
message: string;
}
export interface StatsSummary {
todayVisits: number;
pending: number;
approved: number;
currentlyInside: number;
total: number;
}
export interface BlacklistItem {
id: number;
name: string;
company?: string;
contact?: string;
reason: string;
active: boolean;
createdByName?: string;
createdAt: string;
}
export interface BlacklistCreate {
name: string;
company?: string;
contact?: string;
reason: string;
}
export interface AuditLog {
id: number;
at: string;
actorId?: number;
actorUsername?: string;
action: 'APPROVE' | 'REJECT' | 'BLACKLIST_ADD' | 'BLACKLIST_REMOVE' | 'ADMIN_CONFIG_UPDATE';
targetType?: string;
targetId?: number;
detail?: string;
}
export type DeliveryStatus = 'SENT' | 'FAILED';
export interface PassDelivery {
id: number;
visitRequestId: number;
channel?: string;
recipient?: string;
status: DeliveryStatus;
attempts: number;
lastError?: string;
createdAt: string;
updatedAt: string;
}