397 lines
8.7 KiB
Markdown
397 lines
8.7 KiB
Markdown
|
|
# Plan: Migrate Shared Interfaces to @uptime.link/interfaces
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Move shared type definitions from `catalog_admin/ts_web/interfaces/` to the canonical `../interfaces` package (`@uptime.link/interfaces`) to ensure consistency across all uptime.link packages.
|
||
|
|
|
||
|
|
## Decisions (Resolved)
|
||
|
|
|
||
|
|
1. **Check Config**: Use base type + discriminated union variants (elegant, type-safe)
|
||
|
|
2. **Incident Status**: Create unified type in shared package, migrate both packages
|
||
|
|
3. **Form Interfaces**: Keep local in catalog_admin (UI-specific)
|
||
|
|
4. **Versioning**: Manual releases - will notify when ready to publish
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 1: Add Base Types to Shared Package
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/types.ts`** (new)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Status types for monitors/services
|
||
|
|
export type TStatusType =
|
||
|
|
| 'operational'
|
||
|
|
| 'degraded'
|
||
|
|
| 'partial_outage'
|
||
|
|
| 'major_outage'
|
||
|
|
| 'maintenance'
|
||
|
|
| 'initializing'
|
||
|
|
| 'error'
|
||
|
|
| 'paused';
|
||
|
|
|
||
|
|
// Check types (discriminant values)
|
||
|
|
export type TCheckType = 'assumption' | 'function' | 'pwa' | 'pagerank';
|
||
|
|
|
||
|
|
// Status mode for monitors
|
||
|
|
export type TStatusMode = 'auto' | 'manual';
|
||
|
|
|
||
|
|
// Incident severity
|
||
|
|
export type TIncidentSeverity = 'critical' | 'major' | 'minor' | 'maintenance';
|
||
|
|
|
||
|
|
// Incident status (unified)
|
||
|
|
export type TIncidentStatus =
|
||
|
|
| 'investigating'
|
||
|
|
| 'identified'
|
||
|
|
| 'monitoring'
|
||
|
|
| 'resolved'
|
||
|
|
| 'postmortem';
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 2: Refactor Check Interfaces with Base + Variants
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/checks/index.ts`** (refactor)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { TStatusType, TCheckType } from '../types.js';
|
||
|
|
|
||
|
|
// ============================================
|
||
|
|
// Base Interface
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
export interface ICheckBase {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
description?: string;
|
||
|
|
enabled: boolean;
|
||
|
|
intervalMs?: number;
|
||
|
|
lastRun?: number;
|
||
|
|
lastResult?: 'success' | 'failure' | 'pending';
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================
|
||
|
|
// Discriminated Variants
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
export interface IAssumptionCheck extends ICheckBase {
|
||
|
|
checkType: 'assumption';
|
||
|
|
assumedStatus: TStatusType;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IFunctionCheck extends ICheckBase {
|
||
|
|
checkType: 'function';
|
||
|
|
functionUrl: string;
|
||
|
|
expectedStatusCode?: number;
|
||
|
|
timeoutMs?: number;
|
||
|
|
headers?: Record<string, string>;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IPwaCheck extends ICheckBase {
|
||
|
|
checkType: 'pwa';
|
||
|
|
targetUrl: string;
|
||
|
|
lighthouseThreshold?: number;
|
||
|
|
categories?: ('performance' | 'accessibility' | 'best-practices' | 'seo')[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IPageRankCheck extends ICheckBase {
|
||
|
|
checkType: 'pagerank';
|
||
|
|
targetUrl: string;
|
||
|
|
minimumRank?: number;
|
||
|
|
searchEngine?: 'google' | 'bing';
|
||
|
|
}
|
||
|
|
|
||
|
|
// ============================================
|
||
|
|
// Union Type (for UI and generic handling)
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
export type TCheck =
|
||
|
|
| IAssumptionCheck
|
||
|
|
| IFunctionCheck
|
||
|
|
| IPwaCheck
|
||
|
|
| IPageRankCheck;
|
||
|
|
|
||
|
|
// ============================================
|
||
|
|
// Check Collection
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
export interface ICheckCollection {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
checks: TCheck[];
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 3: Create Unified Incident Interface
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/incident.ts`** (refactor)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { TIncidentSeverity, TIncidentStatus } from './types.js';
|
||
|
|
|
||
|
|
export interface IIncidentUpdate {
|
||
|
|
id: string;
|
||
|
|
incidentId: string;
|
||
|
|
status: TIncidentStatus;
|
||
|
|
message: string;
|
||
|
|
createdAt: number;
|
||
|
|
createdBy?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IIncident {
|
||
|
|
id: string;
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
severity: TIncidentSeverity;
|
||
|
|
status: TIncidentStatus;
|
||
|
|
|
||
|
|
// Affected services
|
||
|
|
affectedServiceIds: string[];
|
||
|
|
|
||
|
|
// Timeline
|
||
|
|
createdAt: number;
|
||
|
|
updatedAt: number;
|
||
|
|
resolvedAt?: number;
|
||
|
|
|
||
|
|
// Updates history
|
||
|
|
updates: IIncidentUpdate[];
|
||
|
|
|
||
|
|
// Metadata
|
||
|
|
createdBy?: string;
|
||
|
|
isScheduled?: boolean;
|
||
|
|
scheduledStartTime?: number;
|
||
|
|
scheduledEndTime?: number;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 4: Add Service Status Interface
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/servicestatus.ts`** (new)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { TStatusType, TStatusMode, TCheckType } from './types.js';
|
||
|
|
|
||
|
|
export interface IServiceStatus {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
displayName: string;
|
||
|
|
description?: string;
|
||
|
|
|
||
|
|
// Current state
|
||
|
|
currentStatus: TStatusType;
|
||
|
|
lastChecked: number;
|
||
|
|
responseTime: number;
|
||
|
|
|
||
|
|
// Uptime metrics
|
||
|
|
uptime30d: number;
|
||
|
|
uptime90d: number;
|
||
|
|
|
||
|
|
// Organization
|
||
|
|
category?: string;
|
||
|
|
dependencies?: string[];
|
||
|
|
|
||
|
|
// Status management
|
||
|
|
statusMode: TStatusMode;
|
||
|
|
manualStatus?: TStatusType;
|
||
|
|
paused: boolean;
|
||
|
|
|
||
|
|
// Check configuration (references check collection)
|
||
|
|
checkType?: TCheckType;
|
||
|
|
checkCollectionId?: string;
|
||
|
|
intervalMs?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IStatusHistoryPoint {
|
||
|
|
timestamp: number;
|
||
|
|
status: TStatusType;
|
||
|
|
responseTime?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IOverallStatus {
|
||
|
|
status: TStatusType;
|
||
|
|
message?: string;
|
||
|
|
lastUpdated: number;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 5: Add Status Page Config
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/statuspageconfig.ts`** (new)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
import { IOverallStatus } from './servicestatus.js';
|
||
|
|
|
||
|
|
export interface IStatusPageConfig {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
slug: string;
|
||
|
|
|
||
|
|
// Branding
|
||
|
|
logoUrl?: string;
|
||
|
|
faviconUrl?: string;
|
||
|
|
primaryColor?: string;
|
||
|
|
|
||
|
|
// Content
|
||
|
|
headerTitle: string;
|
||
|
|
headerDescription?: string;
|
||
|
|
|
||
|
|
// Features
|
||
|
|
showHistoricalUptime: boolean;
|
||
|
|
showResponseTime: boolean;
|
||
|
|
showSubscribeButton: boolean;
|
||
|
|
|
||
|
|
// Service grouping
|
||
|
|
serviceGroups: IServiceGroup[];
|
||
|
|
|
||
|
|
// Overall status override
|
||
|
|
overallStatus?: IOverallStatus;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IServiceGroup {
|
||
|
|
id: string;
|
||
|
|
name: string;
|
||
|
|
description?: string;
|
||
|
|
serviceIds: string[];
|
||
|
|
expanded: boolean;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 6: Update Shared Package Exports
|
||
|
|
|
||
|
|
**File: `../interfaces/ts/data/index.ts`** (update)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
export * from './types.js';
|
||
|
|
export * from './checks/index.js';
|
||
|
|
export * from './incident.js';
|
||
|
|
export * from './servicestatus.js';
|
||
|
|
export * from './statuspageconfig.js';
|
||
|
|
// ... existing exports
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 7: Update catalog_admin Interfaces
|
||
|
|
|
||
|
|
**File: `catalog_admin/ts_web/interfaces/index.ts`** (refactor)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Re-export shared types from @uptime.link/interfaces
|
||
|
|
export {
|
||
|
|
// Types
|
||
|
|
TStatusType,
|
||
|
|
TCheckType,
|
||
|
|
TStatusMode,
|
||
|
|
TIncidentSeverity,
|
||
|
|
TIncidentStatus,
|
||
|
|
|
||
|
|
// Check interfaces
|
||
|
|
ICheckBase,
|
||
|
|
IAssumptionCheck,
|
||
|
|
IFunctionCheck,
|
||
|
|
IPwaCheck,
|
||
|
|
IPageRankCheck,
|
||
|
|
TCheck,
|
||
|
|
ICheckCollection,
|
||
|
|
|
||
|
|
// Incident interfaces
|
||
|
|
IIncident,
|
||
|
|
IIncidentUpdate,
|
||
|
|
|
||
|
|
// Service/Status interfaces
|
||
|
|
IServiceStatus,
|
||
|
|
IStatusHistoryPoint,
|
||
|
|
IOverallStatus,
|
||
|
|
IStatusPageConfig,
|
||
|
|
IServiceGroup,
|
||
|
|
} from '@uptime.link/interfaces';
|
||
|
|
|
||
|
|
// ============================================
|
||
|
|
// Form Interfaces (UI-specific, kept local)
|
||
|
|
// ============================================
|
||
|
|
|
||
|
|
import type { TStatusType, TCheckType, TStatusMode, TIncidentSeverity } from '@uptime.link/interfaces';
|
||
|
|
|
||
|
|
export interface IMonitorFormData {
|
||
|
|
name: string;
|
||
|
|
displayName: string;
|
||
|
|
description?: string;
|
||
|
|
category?: string;
|
||
|
|
checkType: TCheckType;
|
||
|
|
intervalMs: number;
|
||
|
|
statusMode: TStatusMode;
|
||
|
|
paused: boolean;
|
||
|
|
// Check-specific fields (form flattens the discriminated union)
|
||
|
|
assumedStatus?: TStatusType;
|
||
|
|
functionUrl?: string;
|
||
|
|
expectedStatusCode?: number;
|
||
|
|
targetUrl?: string;
|
||
|
|
lighthouseThreshold?: number;
|
||
|
|
minimumRank?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IIncidentFormData {
|
||
|
|
title: string;
|
||
|
|
description: string;
|
||
|
|
severity: TIncidentSeverity;
|
||
|
|
affectedServiceIds: string[];
|
||
|
|
isScheduled: boolean;
|
||
|
|
scheduledStartTime?: number;
|
||
|
|
scheduledEndTime?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface IIncidentUpdateFormData {
|
||
|
|
status: string;
|
||
|
|
message: string;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 8: Update Component Imports
|
||
|
|
|
||
|
|
Scan and update all components that import from local interfaces to ensure they work with the new types. Key files:
|
||
|
|
|
||
|
|
- `ts_web/elements/upladmin-monitor-form/upladmin-monitor-form.ts`
|
||
|
|
- `ts_web/elements/upladmin-monitor-list/upladmin-monitor-list.ts`
|
||
|
|
- `ts_web/elements/upladmin-incident-form/upladmin-incident-form.ts`
|
||
|
|
- `ts_web/elements/upladmin-incident-list/upladmin-incident-list.ts`
|
||
|
|
- `ts_web/elements/upladmin-incident-update/upladmin-incident-update.ts`
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Task 9: Build and Test
|
||
|
|
|
||
|
|
1. Build `../interfaces`: `cd ../interfaces && pnpm build`
|
||
|
|
2. **Notify for release** of `@uptime.link/interfaces`
|
||
|
|
3. Update dependency: `pnpm update @uptime.link/interfaces`
|
||
|
|
4. Build catalog_admin: `pnpm build`
|
||
|
|
5. Verify no type errors
|
||
|
|
6. Test UI components manually
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Files Summary
|
||
|
|
|
||
|
|
### New files in `../interfaces`:
|
||
|
|
- `ts/data/types.ts`
|
||
|
|
- `ts/data/servicestatus.ts`
|
||
|
|
- `ts/data/statuspageconfig.ts`
|
||
|
|
|
||
|
|
### Modified files in `../interfaces`:
|
||
|
|
- `ts/data/checks/index.ts` (refactor to base + variants)
|
||
|
|
- `ts/data/incident.ts` (unified interface)
|
||
|
|
- `ts/data/index.ts` (add exports)
|
||
|
|
|
||
|
|
### Modified files in `catalog_admin`:
|
||
|
|
- `ts_web/interfaces/index.ts` (re-export from shared + local form types)
|
||
|
|
- Component files (if import paths change)
|