feat(elements): add upladmin-option-card component and migrate option/status UIs to use it; refactor monitor form multitoggle subscriptions and event handling; improve theme color handling and dark-mode styles; add demos, Playwright snapshots, and migration plan
This commit is contained in:
396
readme.plan.md
Normal file
396
readme.plan.md
Normal file
@@ -0,0 +1,396 @@
|
||||
# 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)
|
||||
Reference in New Issue
Block a user