commit 8de1de0b4290d2a02824f34a28ca77c18b3e4065 Author: Juergen Kunz Date: Sun Dec 28 17:59:00 2025 +0000 initial diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d09bbe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +./node_modules/ +./dist* \ No newline at end of file diff --git a/readme.hints.md b/readme.hints.md new file mode 100644 index 0000000..f5529c9 --- /dev/null +++ b/readme.hints.md @@ -0,0 +1,149 @@ +# App Building Patterns - Lossless Ecosystem + +This document captures architectural patterns and conventions used across the lossless ecosystem, based on analysis of stack.gallery, serve.zone/onebox, idp.global, and uptime.link projects. + +## Runtime & Build System + +- **Deno** preferred for new projects (stack.gallery, onebox) +- **Node.js** for legacy/complex projects (idp.global) +- Build tools: `@git.zone/tsbuild`, `@git.zone/tsbundle`, `@git.zone/tswatch` +- Package manager: **pnpm** exclusively + +## Project Structure Pattern + +``` +project/ +├── ts/ # Backend TypeScript +│ ├── index.ts # Entry/exports +│ ├── plugins.ts # Centralized dependency imports +│ ├── classes/ # Core business logic classes +│ ├── models/ # Database models (SmartData) +│ ├── services/ # Service layer +│ └── api/ # API handlers +├── ui/ # Angular 19 frontend (Deno projects) +├── ts_web/ # Web components (Node projects) +│ ├── elements/ # Web components +│ ├── pages/ # Page templates +│ ├── interfaces/ # Local interfaces +│ ├── styles/ # Shared styles +│ └── index.ts # Public exports +├── ts_interfaces/ # Shared TypeScript interfaces +├── mod.ts # Deno entry point +├── cli.js # Node.js entry point +└── deno.json/package.json +``` + +## Core Framework Stack + +| Layer | Technology | +|-------|------------| +| Database | MongoDB via `@push.rocks/smartdata` | +| HTTP Server (Deno) | Native `Deno.serve()` | +| HTTP Server (Node) | `@api.global/typedserver` | +| RPC | `@api.global/typedrequest` for type-safe client-server | +| WebSocket | `@api.global/typedsocket` | +| State | `@push.rocks/smartstate` (RxJS-based) | + +## Frontend Patterns + +### Deno Projects (stack.gallery, onebox) +- Angular 19 with zoneless change detection +- Tailwind CSS for styling +- Standalone components (no NgModules) + +### Node Projects (idp.global, uptime.link) +- Web Components via `@design.estate/dees-element` (LitElement wrapper) +- UI components from `@design.estate/dees-catalog` +- State management via `@push.rocks/smartstate` with RxJS + +### Web Component Pattern +```typescript +@customElement('element-name') +export class ElementName extends DeesElement { + @property() accessor propertyName: type; + + public static styles = [cssManager.defaultStyles, css`...`]; + public render(): TemplateResult { return html`...`; } +} +``` + +## Key Dependencies (@push.rocks ecosystem) + +| Package | Purpose | +|---------|---------| +| smartdata | MongoDB ORM with decorators | +| smartacme | Let's Encrypt/ACME certificates | +| smartjwt | JWT handling | +| smartlog | Structured logging | +| smartenv/qenv | Environment configuration | +| smartpromise | Promise utilities | +| smartrx | RxJS utilities | +| smartstate | State management | +| smartunique | UUID generation | +| taskbuffer | Task scheduling | +| smartnetwork | Network operations | +| smarturl | URL parsing | + +## Architectural Patterns + +1. **Manager Pattern**: Main orchestrator class with specialized managers + ```typescript + class MainApp { + public userManager = new UserManager(this); + public authManager = new AuthManager(this); + // ... + } + ``` + +2. **Repository Pattern**: Database access via repositories + ```typescript + class UserRepository extends BaseRepository { + // CRUD methods + } + ``` + +3. **Plugin Injection**: All deps imported via `plugins.ts` + ```typescript + // ts/plugins.ts + import * as smartdata from '@push.rocks/smartdata'; + export { smartdata }; + + // Usage: plugins.smartdata.Collection(...) + ``` + +4. **Type-Safe RPC**: TypedRequest/TypedRouter for API + ```typescript + typedrouter.addHandler(requestInterface, handler); + ``` + +5. **Lazy Database**: `@Collection(() => db)` decorator pattern + +## Deployment + +- **Deno**: Compile to single binary with embedded UI +- **Docker**: Multi-stage builds (build → production → alpine) +- **Systemd**: Integration via `@push.rocks/smartdaemon` + +## Design Tokens (catalog) + +- Fonts: Geist Sans/Mono +- Status colors: operational, degraded, partial, major, maintenance +- Spacing scale: xs(4px) to 4xl(96px) +- Shadow system, border radius tokens +- Dark/light mode via `cssManager.bdTheme()` + +## React Alternative (about.uptime.link) + +For marketing/info sites: +- React 18 + Vite for build +- Radix UI for accessible components +- TanStack React Query for data fetching +- React Hook Form + Zod for forms +- Tailwind CSS + PostCSS + +## Testing + +- Framework: `@git.zone/tstest` with `@git.zone/tstest/tapbundle` as reporter framework. It simply is imported in testfiles: e.g. ./test/test.some.ts would say `import {tap, expect} from '@git.zone/tstest/tapbundle'` and `tap.test('some description', async (toolsArg) => { await expect(someValue)}).toEqual(expectedValue) })` +- File patterns: `*.ts` (Node), `*.browser.ts` (browser-specific) +- Command: `tstest test/ --verbose` +- Type checking: `tsbuild check test/**/* --skiplibcheck` (test only) diff --git a/stories/01-monitoring-detection.md b/stories/01-monitoring-detection.md new file mode 100644 index 0000000..08b4e3b --- /dev/null +++ b/stories/01-monitoring-detection.md @@ -0,0 +1,108 @@ +# Monitoring & Detection User Stories + +User stories for the `@uptime.link/detector` functionality. + +--- + +### US-MD-01: Configure HTTP/HTTPS Service Monitoring + +**As a** DevOps/SRE Engineer, +**I want** to configure monitoring for HTTP and HTTPS endpoints, +**So that** I can track the availability and health of my web services. + +#### Acceptance Criteria +- [ ] Can specify URL with protocol (http:// or https://) +- [ ] Can configure expected response status codes +- [ ] Can set connection timeout thresholds +- [ ] SSL certificate validation is performed for HTTPS +- [ ] Receives alerts when service becomes unreachable + +--- + +### US-MD-02: Monitor Database Services + +**As a** DevOps/SRE Engineer, +**I want** to monitor database services (MySQL, PostgreSQL, MongoDB, Redis), +**So that** I can ensure my data layer is operational. + +#### Acceptance Criteria +- [ ] Can configure connection parameters for each database type +- [ ] Service type is auto-detected based on port and protocol +- [ ] Connection health is verified periodically +- [ ] Can distinguish between connection refused vs timeout +- [ ] Receives specific error context on failure + +--- + +### US-MD-03: Set Up Port Availability Checks + +**As a** DevOps/SRE Engineer, +**I want** to check if specific ports are open and accepting connections, +**So that** I can monitor infrastructure services beyond HTTP. + +#### Acceptance Criteria +- [ ] Can specify host and port combinations +- [ ] Can check both local and remote ports +- [ ] Receives response indicating port open/closed/filtered +- [ ] Can configure check intervals +- [ ] Supports common protocols (SSH, FTP, SMTP) + +--- + +### US-MD-04: Configure Monitoring Intervals + +**As a** DevOps/SRE Engineer, +**I want** to define how frequently each service is checked, +**So that** I can balance between early detection and resource usage. + +#### Acceptance Criteria +- [ ] Can set interval per monitored service +- [ ] Can choose from preset intervals (30s, 1m, 5m, 15m) +- [ ] Can configure custom intervals +- [ ] Intervals are respected within acceptable variance +- [ ] Can pause/resume monitoring without losing configuration + +--- + +### US-MD-05: Service Type Auto-Detection + +**As a** DevOps/SRE Engineer, +**I want** the system to automatically detect the type of service running on a port, +**So that** I can quickly onboard services without manual configuration. + +#### Acceptance Criteria +- [ ] Detects HTTP/HTTPS services via protocol handshake +- [ ] Identifies SSH via banner detection +- [ ] Recognizes database protocols (MySQL, PostgreSQL, MongoDB, Redis) +- [ ] Returns service type in detection results +- [ ] Handles unrecognized services gracefully + +--- + +### US-MD-06: Configure Alert Thresholds + +**As a** DevOps/SRE Engineer, +**I want** to set thresholds for when alerts should be triggered, +**So that** I avoid alert fatigue from transient issues. + +#### Acceptance Criteria +- [ ] Can configure number of consecutive failures before alerting +- [ ] Can set response time degradation thresholds +- [ ] Can define recovery confirmation count before marking operational +- [ ] Thresholds apply per-service +- [ ] Can set different thresholds for different severity levels + +--- + +### US-MD-07: View Real-Time Detection Results + +**As a** DevOps/SRE Engineer, +**I want** to see the current status of all monitored services in real-time, +**So that** I can quickly assess infrastructure health. + +#### Acceptance Criteria +- [ ] Dashboard shows all monitored services +- [ ] Status updates within configured interval +- [ ] Shows last check timestamp +- [ ] Displays response time metrics +- [ ] Indicates service type for each endpoint diff --git a/stories/02-status-page.md b/stories/02-status-page.md new file mode 100644 index 0000000..5e28948 --- /dev/null +++ b/stories/02-status-page.md @@ -0,0 +1,123 @@ +# Status Page User Stories + +User stories for the `@uptime.link/statuspage` (catalog) web components. + +--- + +### US-SP-01: Create a Status Page + +**As a** DevOps/SRE Engineer, +**I want** to create a public status page for my services, +**So that** my users can check service availability without contacting support. + +#### Acceptance Criteria +- [ ] Can create a new status page instance +- [ ] Page displays overall system status +- [ ] Shows list of monitored services/assets +- [ ] Accessible via custom subdomain or path +- [ ] Loads quickly and responsively + +--- + +### US-SP-02: Configure Status Page Branding + +**As a** DevOps/SRE Engineer, +**I want** to customize the branding of my status page, +**So that** it matches my company's visual identity. + +#### Acceptance Criteria +- [ ] Can set custom logo in header +- [ ] Can configure company name and tagline +- [ ] Can customize primary colors +- [ ] Can add custom footer content and links +- [ ] Changes reflect immediately on the page + +--- + +### US-SP-03: Manage Monitored Assets + +**As a** DevOps/SRE Engineer, +**I want** to add, remove, and organize services displayed on the status page, +**So that** users see only relevant services. + +#### Acceptance Criteria +- [ ] Can add new services with name and description +- [ ] Can group services by category +- [ ] Can reorder services within groups +- [ ] Can hide services from public view +- [ ] Can archive services without deletion + +--- + +### US-SP-04: View Uptime Statistics + +**As a** DevOps/SRE Engineer, +**I want** to display uptime percentages for each service, +**So that** users can see historical reliability. + +#### Acceptance Criteria +- [ ] Shows uptime percentage for last 24 hours +- [ ] Shows uptime percentage for last 7 days +- [ ] Shows uptime percentage for last 30 days +- [ ] Stats update automatically +- [ ] Can display response time averages + +--- + +### US-SP-05: View Hourly Status Timeline + +**As a** DevOps/SRE Engineer, +**I want** to show an hourly status timeline for services, +**So that** users can see recent status patterns at a glance. + +#### Acceptance Criteria +- [ ] Displays last 24 hours as horizontal bar segments +- [ ] Each segment color-coded by status (operational, degraded, outage) +- [ ] Hovering shows exact time and status +- [ ] Timeline is responsive on mobile +- [ ] Clear visual distinction between status states + +--- + +### US-SP-06: View Monthly Uptime Calendar + +**As a** DevOps/SRE Engineer, +**I want** to display a monthly calendar showing daily uptime, +**So that** users can see longer-term reliability trends. + +#### Acceptance Criteria +- [ ] Shows current month as calendar grid +- [ ] Each day color-coded by uptime level +- [ ] Can navigate to previous months +- [ ] Clicking a day shows detailed breakdown +- [ ] Shows uptime percentage summary for the month + +--- + +### US-SP-07: Configure Dark/Light Theme + +**As a** DevOps/SRE Engineer, +**I want** my status page to support dark and light themes, +**So that** users can view it comfortably in any environment. + +#### Acceptance Criteria +- [ ] Supports automatic theme based on user's system preference +- [ ] Can force light or dark mode +- [ ] Theme toggle is accessible on the page +- [ ] All components render correctly in both themes +- [ ] Custom brand colors adapt appropriately + +--- + +### US-SP-08: Subscribe to Status Updates + +**As a** DevOps/SRE Engineer, +**I want** users to subscribe to status notifications, +**So that** they're proactively informed of issues. + +#### Acceptance Criteria +- [ ] Subscribe form available in footer +- [ ] Supports email subscription +- [ ] Can configure notification preferences +- [ ] Subscription is confirmed via double opt-in +- [ ] Can unsubscribe easily diff --git a/stories/03-incident-management.md b/stories/03-incident-management.md new file mode 100644 index 0000000..792c244 --- /dev/null +++ b/stories/03-incident-management.md @@ -0,0 +1,93 @@ +# Incident Management User Stories + +User stories for incident lifecycle management. + +--- + +### US-IM-01: Create a New Incident + +**As a** DevOps/SRE Engineer, +**I want** to create an incident when a service issue occurs, +**So that** users are informed about ongoing problems. + +#### Acceptance Criteria +- [ ] Can create incident with title and description +- [ ] Can select affected services +- [ ] Can set incident severity (major, minor, degraded) +- [ ] Can set incident status (investigating, identified, monitoring, resolved) +- [ ] Incident appears on status page immediately + +--- + +### US-IM-02: Post Incident Updates + +**As a** DevOps/SRE Engineer, +**I want** to post updates to an ongoing incident, +**So that** users stay informed about our progress. + +#### Acceptance Criteria +- [ ] Can add timestamped updates to an incident +- [ ] Can change incident status with each update +- [ ] Updates appear in chronological order +- [ ] Can edit previous updates if needed +- [ ] Subscribers receive update notifications + +--- + +### US-IM-03: Resolve an Incident + +**As a** DevOps/SRE Engineer, +**I want** to mark an incident as resolved, +**So that** users know the issue has been fixed. + +#### Acceptance Criteria +- [ ] Can set incident status to resolved +- [ ] Must provide resolution message +- [ ] Resolution timestamp is recorded +- [ ] Affected services return to operational status +- [ ] Incident moves to historical view + +--- + +### US-IM-04: View Incident History + +**As a** DevOps/SRE Engineer, +**I want** users to view past incidents, +**So that** they can see our track record and responses. + +#### Acceptance Criteria +- [ ] Displays list of past incidents +- [ ] Can filter by date range +- [ ] Can filter by affected service +- [ ] Each incident shows full timeline +- [ ] Can paginate through older incidents + +--- + +### US-IM-05: Schedule Maintenance Windows + +**As a** DevOps/SRE Engineer, +**I want** to schedule planned maintenance in advance, +**So that** users know about upcoming downtime. + +#### Acceptance Criteria +- [ ] Can create maintenance with start and end times +- [ ] Can specify affected services +- [ ] Maintenance appears on status page before it starts +- [ ] Automatic status change at scheduled time +- [ ] Automatic return to operational when maintenance ends + +--- + +### US-IM-06: Automatic Incident Creation + +**As a** DevOps/SRE Engineer, +**I want** incidents to be created automatically when monitoring detects issues, +**So that** users are informed without manual intervention. + +#### Acceptance Criteria +- [ ] Incident created when service goes down +- [ ] Auto-generated incident includes service name +- [ ] Initial status set to "investigating" +- [ ] Can be converted to manual management +- [ ] Auto-resolves when service recovers (configurable) diff --git a/stories/04-widget-integration.md b/stories/04-widget-integration.md new file mode 100644 index 0000000..6216cee --- /dev/null +++ b/stories/04-widget-integration.md @@ -0,0 +1,63 @@ +# Widget Integration User Stories + +User stories for the `@uptimelink/webwidget` embeddable component. + +--- + +### US-WI-01: Embed Status Widget on External Site + +**As a** DevOps/SRE Engineer, +**I want** to embed a status widget on my own website or application, +**So that** users see current status without leaving my site. + +#### Acceptance Criteria +- [ ] Widget available as web component +- [ ] Simple embed code (script tag + element) +- [ ] Widget loads asynchronously without blocking page +- [ ] Works on any website regardless of framework +- [ ] Minimal footprint (small bundle size) + +--- + +### US-WI-02: Customize Widget Appearance + +**As a** DevOps/SRE Engineer, +**I want** to customize how the status widget looks, +**So that** it integrates seamlessly with my site design. + +#### Acceptance Criteria +- [ ] Can configure widget size (compact, standard, expanded) +- [ ] Can set custom colors to match brand +- [ ] Supports dark and light themes +- [ ] Can show/hide specific elements (logo, uptime %, etc.) +- [ ] CSS custom properties available for advanced styling + +--- + +### US-WI-03: Configure Widget Behavior + +**As a** DevOps/SRE Engineer, +**I want** to configure how the widget behaves, +**So that** it provides the right level of detail. + +#### Acceptance Criteria +- [ ] Can configure which services to display +- [ ] Can set refresh interval +- [ ] Can enable/disable expandable view on hover +- [ ] Can link to full status page on click +- [ ] Can show/hide incident information + +--- + +### US-WI-04: Widget Status Indicator Badge + +**As a** DevOps/SRE Engineer, +**I want** a minimal status badge for compact spaces, +**So that** I can show status in headers or footers. + +#### Acceptance Criteria +- [ ] Minimal badge showing overall status +- [ ] Color-coded (green/yellow/red) +- [ ] Tooltip shows more detail on hover +- [ ] Links to full status page +- [ ] Under 10KB bundle size diff --git a/stories/05-cli-operations.md b/stories/05-cli-operations.md new file mode 100644 index 0000000..0138af9 --- /dev/null +++ b/stories/05-cli-operations.md @@ -0,0 +1,78 @@ +# CLI Operations User Stories + +User stories for the `@uptime.link/cli` command-line interface. + +--- + +### US-CLI-01: Check Service Status via CLI + +**As a** DevOps/SRE Engineer, +**I want** to check the status of monitored services from the command line, +**So that** I can quickly verify health in terminal-based workflows. + +#### Acceptance Criteria +- [ ] Command returns current status of all services +- [ ] Can filter by specific service name +- [ ] Output includes status, uptime %, and last check time +- [ ] Exit code reflects overall health (0 = all operational) +- [ ] Supports JSON output format for scripting + +--- + +### US-CLI-02: Configure Monitoring from Command Line + +**As a** DevOps/SRE Engineer, +**I want** to add and configure monitored services via CLI, +**So that** I can manage monitoring in infrastructure-as-code workflows. + +#### Acceptance Criteria +- [ ] Can add new service to monitor +- [ ] Can specify URL, port, and service type +- [ ] Can set check interval +- [ ] Can remove services from monitoring +- [ ] Configuration persists across CLI sessions + +--- + +### US-CLI-03: Create Incidents via CLI + +**As a** DevOps/SRE Engineer, +**I want** to create and manage incidents from the command line, +**So that** I can respond to issues from any terminal. + +#### Acceptance Criteria +- [ ] Can create new incident with title and description +- [ ] Can post updates to existing incidents +- [ ] Can resolve incidents +- [ ] Can list active incidents +- [ ] Supports interactive and non-interactive modes + +--- + +### US-CLI-04: Integrate CLI in CI/CD Pipelines + +**As a** DevOps/SRE Engineer, +**I want** to use the CLI in automated pipelines, +**So that** I can gate deployments on service health. + +#### Acceptance Criteria +- [ ] CLI works without interactive prompts (--yes flag) +- [ ] Authentication via environment variables or tokens +- [ ] Returns appropriate exit codes for automation +- [ ] Timeout configurable for health checks +- [ ] Integrates with common CI systems (GitHub Actions, GitLab CI) + +--- + +### US-CLI-05: Run One-Time Health Checks + +**As a** DevOps/SRE Engineer, +**I want** to run ad-hoc health checks on arbitrary URLs, +**So that** I can verify connectivity during troubleshooting. + +#### Acceptance Criteria +- [ ] Can check any URL/port without configuration +- [ ] Returns detailed connection information +- [ ] Shows response time metrics +- [ ] Detects service type automatically +- [ ] Provides verbose mode for debugging diff --git a/stories/06-api-integration.md b/stories/06-api-integration.md new file mode 100644 index 0000000..8fcb9ab --- /dev/null +++ b/stories/06-api-integration.md @@ -0,0 +1,78 @@ +# API Integration User Stories + +User stories for the `@uptime.link/api` programmatic access. + +--- + +### US-API-01: Retrieve Service Status via API + +**As a** DevOps/SRE Engineer, +**I want** to fetch current service status programmatically, +**So that** I can integrate status data into custom dashboards. + +#### Acceptance Criteria +- [ ] REST endpoint returns all service statuses +- [ ] Can filter by service ID or group +- [ ] Response includes uptime metrics +- [ ] Supports JSON response format +- [ ] API is versioned for backward compatibility + +--- + +### US-API-02: Manage Incidents via API + +**As a** DevOps/SRE Engineer, +**I want** to create and update incidents through the API, +**So that** I can automate incident management workflows. + +#### Acceptance Criteria +- [ ] Can create incidents via POST request +- [ ] Can post updates to incidents +- [ ] Can change incident status +- [ ] Can list and filter incidents +- [ ] Returns incident ID for reference + +--- + +### US-API-03: Configure Monitoring via API + +**As a** DevOps/SRE Engineer, +**I want** to manage monitored services through the API, +**So that** I can integrate with infrastructure automation tools. + +#### Acceptance Criteria +- [ ] Can add new services to monitor +- [ ] Can update service configuration +- [ ] Can delete services +- [ ] Can retrieve current configuration +- [ ] Supports bulk operations + +--- + +### US-API-04: Webhook Notifications + +**As a** DevOps/SRE Engineer, +**I want** to receive webhook notifications when status changes, +**So that** I can trigger automated responses to incidents. + +#### Acceptance Criteria +- [ ] Can configure webhook URLs +- [ ] Webhooks fire on status changes +- [ ] Webhooks fire on incident creation/updates +- [ ] Payload includes full status details +- [ ] Supports webhook signature verification + +--- + +### US-API-05: API Authentication + +**As a** DevOps/SRE Engineer, +**I want** secure authentication for API access, +**So that** only authorized systems can manage my status page. + +#### Acceptance Criteria +- [ ] API keys for service-to-service auth +- [ ] Keys can be created and revoked +- [ ] Can set permissions per key (read-only, full access) +- [ ] Rate limiting to prevent abuse +- [ ] Audit log of API access diff --git a/ts_api/00_commitinfo_data.ts b/ts_api/00_commitinfo_data.ts new file mode 100644 index 0000000..fb33806 --- /dev/null +++ b/ts_api/00_commitinfo_data.ts @@ -0,0 +1,8 @@ +/** + * autocreated commitinfo by @pushrocks/commitinfo + */ +export const commitinfo = { + name: '@uptime.link/api', + version: '2.0.0', + description: 'the api package for uptime.link' +} diff --git a/ts_api/index.ts b/ts_api/index.ts new file mode 100644 index 0000000..257c573 --- /dev/null +++ b/ts_api/index.ts @@ -0,0 +1,3 @@ +import * as plugins from './uplapi.plugins.js'; + +export let demoExport = 'Hi there! :) This is an exported string'; diff --git a/ts_api/uplapi.plugins.ts b/ts_api/uplapi.plugins.ts new file mode 100644 index 0000000..29aa9da --- /dev/null +++ b/ts_api/uplapi.plugins.ts @@ -0,0 +1,2 @@ +const removeme = {}; +export { removeme }; diff --git a/ts_cli/00_commitinfo_data.ts b/ts_cli/00_commitinfo_data.ts new file mode 100644 index 0000000..1d5595a --- /dev/null +++ b/ts_cli/00_commitinfo_data.ts @@ -0,0 +1,8 @@ +/** + * autocreated commitinfo by @pushrocks/commitinfo + */ +export const commitinfo = { + name: '@uptime.link/cli', + version: '1.0.2', + description: 'the cli for uptime.link' +} diff --git a/ts_cli/index.ts b/ts_cli/index.ts new file mode 100644 index 0000000..fc968a7 --- /dev/null +++ b/ts_cli/index.ts @@ -0,0 +1,3 @@ +import * as plugins from './uplcli.plugins.js'; + +export let demoExport = 'Hi there! :) This is an exported string'; diff --git a/ts_cli/uplcli.plugins.ts b/ts_cli/uplcli.plugins.ts new file mode 100644 index 0000000..29aa9da --- /dev/null +++ b/ts_cli/uplcli.plugins.ts @@ -0,0 +1,2 @@ +const removeme = {}; +export { removeme }; diff --git a/ts_interfaces/00_commitinfo_data.ts b/ts_interfaces/00_commitinfo_data.ts new file mode 100644 index 0000000..1b91a1b --- /dev/null +++ b/ts_interfaces/00_commitinfo_data.ts @@ -0,0 +1,8 @@ +/** + * autocreated commitinfo by @push.rocks/commitinfo + */ +export const commitinfo = { + name: '@uptime.link/interfaces', + version: '2.1.0', + description: 'TypeScript interface for the uptime.link API and modules' +} diff --git a/ts_interfaces/data/checkcollection.ts b/ts_interfaces/data/checkcollection.ts new file mode 100644 index 0000000..f35f456 --- /dev/null +++ b/ts_interfaces/data/checkcollection.ts @@ -0,0 +1,24 @@ +import type * as checks from './checks/index.js'; + +/** + * A collection of checks to run against a property/service. + * + * Two storage modes supported: + * 1. Legacy: Separate arrays for each check type (assumptionChecks, functionChecks, etc.) + * 2. Modern: Single unified array using discriminated union (checks) + */ +export interface ICheckCollection { + id: string; + name?: string; + description?: string; + intervalMs: number; + + // Modern: Single array with discriminated union + checks?: checks.TCheckConfig[]; + + // Legacy: Separate arrays by type (for backward compatibility) + assumptionChecks?: checks.IAssumptionCheck[]; + functionChecks?: checks.IFunctionCheck[]; + pwaChecks?: checks.IPwaCheck[]; + pageRankChecks?: checks.IPageRankCheck[]; +} diff --git a/ts_interfaces/data/checks/assumption.check.ts b/ts_interfaces/data/checks/assumption.check.ts new file mode 100644 index 0000000..31e629f --- /dev/null +++ b/ts_interfaces/data/checks/assumption.check.ts @@ -0,0 +1,28 @@ +import type * as plugins from '../../ul-interfaces.plugins.js'; +import type { TCheckResultStatus } from '../types.js'; +import type { TExecutionTiming } from './index.js'; + +/** + * Assumption check execution data. + * Used by check runners to store input and results. + */ +export interface IAssumptionCheck { + inputData: { + domain: string; + title?: string; + statusCode?: string; + description?: string; + dnsRecords?: plugins.tsclass.network.IDnsRecord; + }; + executionResults: Array<{ + timing: TExecutionTiming; + status: TCheckResultStatus; + data: { + domain: string; + title?: string; + statusCode?: string; + description?: string; + dnsRecords: Array; + }; + }>; +} diff --git a/ts_interfaces/data/checks/function.check.ts b/ts_interfaces/data/checks/function.check.ts new file mode 100644 index 0000000..901b552 --- /dev/null +++ b/ts_interfaces/data/checks/function.check.ts @@ -0,0 +1,20 @@ +import type { TCheckResultStatus } from '../types.js'; +import type { TExecutionTiming } from './index.js'; + +/** + * Function check execution data. + * Used by check runners to store input and results. + */ +export interface IFunctionCheck { + checkId: string; + inputData: { + domain: string; + functionDef: string; + }; + executionResults: Array<{ + timing: TExecutionTiming; + status: TCheckResultStatus; + data: any; + checkLog: string[]; + }>; +} diff --git a/ts_interfaces/data/checks/index.ts b/ts_interfaces/data/checks/index.ts new file mode 100644 index 0000000..ec40795 --- /dev/null +++ b/ts_interfaces/data/checks/index.ts @@ -0,0 +1,117 @@ +import type { TStatusType, TCheckResultStatus, TCheckLastResult } from '../types.js'; + +// ============================================ +// Execution Timing (used by check runners) +// ============================================ + +export interface TExecutionTiming { + plannedTime: number; + timeStarted: number; + timeEnded: number; + duration: number; +} + +// Re-export for backward compatibility +export type { TCheckResultStatus }; + +// ============================================ +// Check Configuration Base Interface +// ============================================ + +/** + * Base interface for all check configurations. + * Extended by discriminated variants. + */ +export interface ICheckBase { + id: string; + name: string; + description?: string; + enabled: boolean; + intervalMs?: number; + lastRun?: number; + lastResult?: TCheckLastResult; +} + +// ============================================ +// Discriminated Check Variants (Configuration) +// ============================================ + +/** + * Assumption check - assumes a status without active verification + */ +export interface IAssumptionCheckConfig extends ICheckBase { + checkType: 'assumption'; + assumedStatus: TStatusType; + domain?: string; + title?: string; + statusCode?: string; +} + +/** + * Function check - calls a URL and validates response + */ +export interface IFunctionCheckConfig extends ICheckBase { + checkType: 'function'; + functionUrl: string; + domain?: string; + expectedStatusCode?: number; + timeoutMs?: number; + headers?: Record; +} + +/** + * PWA check - validates Progressive Web App criteria + */ +export interface IPwaCheckConfig extends ICheckBase { + checkType: 'pwa'; + targetUrl: string; + domain?: string; + lighthouseThreshold?: number; + categories?: ('performance' | 'accessibility' | 'best-practices' | 'seo')[]; +} + +/** + * PageRank check - validates search engine ranking + */ +export interface IPageRankCheckConfig extends ICheckBase { + checkType: 'pagerank'; + targetUrl: string; + domain?: string; + searchTerm: string; + minimumRank?: number; + checkGoogle?: boolean; + checkBing?: boolean; + googleMinRank?: number; + bingMinRank?: number; +} + +// ============================================ +// Union Type (for UI and generic handling) +// ============================================ + +/** + * Union of all check configuration types. + * Use `checkType` discriminant for type narrowing. + * + * @example + * function handleCheck(check: TCheckConfig) { + * if (check.checkType === 'function') { + * console.log(check.functionUrl); // TypeScript knows this exists + * } + * } + */ +export type TCheckConfig = + | IAssumptionCheckConfig + | IFunctionCheckConfig + | IPwaCheckConfig + | IPageRankCheckConfig; + +// ============================================ +// Execution Interfaces (Runtime Data) +// ============================================ + +// Keep existing execution interfaces for backward compatibility +export * from './assumption.check.js'; +export * from './function.check.js'; +export * from './pagerank.check.js'; +export * from './pwa.check.js'; diff --git a/ts_interfaces/data/checks/pagerank.check.ts b/ts_interfaces/data/checks/pagerank.check.ts new file mode 100644 index 0000000..57727db --- /dev/null +++ b/ts_interfaces/data/checks/pagerank.check.ts @@ -0,0 +1,24 @@ +import type * as search from '../search.js'; +import type { TCheckResultStatus } from '../types.js'; +import type { TExecutionTiming } from './index.js'; + +/** + * PageRank check execution data. + * Used by check runners to store input and results. + */ +export interface IPageRankCheck { + inputData: { + subId: string; + domain: string; + searchTerm: string; + checkBing?: boolean; + checkGoogle?: boolean; + bingMinRank?: number; + googleMinRank?: number; + }; + executionResults: Array<{ + timing: TExecutionTiming; + status: TCheckResultStatus; + pageRankResult: search.IPageRankResult; + }>; +} diff --git a/ts_interfaces/data/checks/pwa.check.ts b/ts_interfaces/data/checks/pwa.check.ts new file mode 100644 index 0000000..d27acd6 --- /dev/null +++ b/ts_interfaces/data/checks/pwa.check.ts @@ -0,0 +1,22 @@ +import type { TCheckResultStatus } from '../types.js'; + +/** + * PWA check execution data. + * Used by check runners to store input and results. + */ +export interface IPwaCheck { + inputData: { + domain: string; + }; + executionResults: Array<{ + subId: string; + timeStarted: number; + timeEnded: number; + duration: number; + status: TCheckResultStatus; + data: { + lhr: any; + reports: any[]; + }; + }>; +} diff --git a/ts_interfaces/data/domainsnapshot.ts b/ts_interfaces/data/domainsnapshot.ts new file mode 100644 index 0000000..be3c0c2 --- /dev/null +++ b/ts_interfaces/data/domainsnapshot.ts @@ -0,0 +1,31 @@ +import * as plugins from '../ul-interfaces.plugins.js'; +import type { ILinkSnapshot } from './linksnapshot.js'; + +export interface IDomainSnapshot { + registration: { + isRegistered: boolean; + updatedDate: number; + createdDate: number; + expiryDate: number; + }; + delegation: plugins.tsclass.network.IDomainDelegation; + phishingFlags: { + listName: string; + }[]; + recordScans: { + identifier: string; + nameservers: string[]; + aRecords: plugins.tsclass.network.IDnsRecord[]; + aaaaRecords: plugins.tsclass.network.IDnsRecord[]; + txtRecords: plugins.tsclass.network.IDnsRecord[]; + mxRecords: plugins.tsclass.network.IDnsRecord[]; + specialRecords: { + dmarc: plugins.tsclass.network.IDnsRecord[]; + } + }[]; + linkSnapshots: ILinkSnapshot[]; + whoisServers: { + serverUrl: string; + content: string; + }[]; +} diff --git a/ts_interfaces/data/incident.ts b/ts_interfaces/data/incident.ts new file mode 100644 index 0000000..092537a --- /dev/null +++ b/ts_interfaces/data/incident.ts @@ -0,0 +1,81 @@ +import type { TIncidentSeverity, TIncidentStatus } from './types.js'; + +// ============================================ +// Incident Update +// ============================================ + +/** + * A single update within an incident timeline. + */ +export interface IIncidentUpdate { + id: string; + incidentId: string; + status: TIncidentStatus; + message: string; + createdAt: number; + createdBy?: string; + type?: 'comment' | 'status_change' | 'automatic'; +} + +// ============================================ +// Incident +// ============================================ + +/** + * Represents an incident affecting one or more services. + */ +export interface IIncident { + id: string; + title: string; + description: string; + severity: TIncidentSeverity; + status: TIncidentStatus; + + // Affected services + affectedServiceIds: string[]; + + // Timeline + createdAt: number; + updatedAt: number; + resolvedAt?: number; + firstResponseAt?: number; + + // Updates history + updates: IIncidentUpdate[]; + + // Metadata + createdBy?: string; + assignedUserId?: string; + creationMode?: 'monitor' | 'manual'; + + // Scheduled maintenance + isScheduled?: boolean; + scheduledStartTime?: number; + scheduledEndTime?: number; + + // Post-incident + postMortemLink?: string; +} + +// ============================================ +// Legacy Interface (for backward compatibility) +// ============================================ + +/** + * @deprecated Use IIncident instead + */ +export interface IIncidentLegacy { + timestamp: number; + firstResponseTimestamp?: number; + status: 'discovered' | 'investigating' | 'fixing' | 'fixImplemented' | 'watching' | 'resolved'; + creationMode: 'monitor' | 'manual'; + assignedUserId?: string; + postMortemLink?: string; + updates: { + markdownText: string; + type: 'comment' | 'manualUpdate' | 'automaticUpdate'; + }[]; + justForLooks: { + isoTimestamp: string; + }; +} diff --git a/ts_interfaces/data/index.ts b/ts_interfaces/data/index.ts new file mode 100644 index 0000000..f7e583f --- /dev/null +++ b/ts_interfaces/data/index.ts @@ -0,0 +1,32 @@ +// Core types +export * from './types.js'; + +// Check interfaces (configuration + execution) +export * from './checks/index.js'; + +// Collections +export * from './checkcollection.js'; + +// Incidents +export * from './incident.js'; + +// Service status +export * from './servicestatus.js'; + +// Status page configuration +export * from './statuspageconfig.js'; + +// Domain and link snapshots +export * from './domainsnapshot.js'; +export * from './linksnapshot.js'; + +// Property and search +export * from './property.js'; +export * from './search.js'; + +// Status (90-day history) +export * from './status.js'; + +// Re-export checks namespace for convenience +import * as checks from './checks/index.js'; +export { checks }; diff --git a/ts_interfaces/data/linksnapshot.ts b/ts_interfaces/data/linksnapshot.ts new file mode 100644 index 0000000..7144947 --- /dev/null +++ b/ts_interfaces/data/linksnapshot.ts @@ -0,0 +1,29 @@ +import * as plugins from '../ul-interfaces.plugins.js'; + +export interface ILinkSnapshot { + /** + * the link base on which the snapshot was taken + */ + linkBaseUrl: string; + httpsSupport: boolean; + httpHttpsParity: boolean; + httpToHttpsRedirect: boolean; + fromWwwRedirect: boolean; + toWwwRedirect: boolean; + statusCode: number; + fullPageLoadSize: number; + fullPageLoadTimeMs: number; + cookies: any[]; + httpRequest: { + statusCode: number; + headers: { + [key: string]: string; + } + }; + httpsRequest: { + statusCode: number; + headers: { + [key: string]: string; + } + }; +} \ No newline at end of file diff --git a/ts_interfaces/data/property.ts b/ts_interfaces/data/property.ts new file mode 100644 index 0000000..8897843 --- /dev/null +++ b/ts_interfaces/data/property.ts @@ -0,0 +1,10 @@ +import * as plugins from '../ul-interfaces.plugins.js'; + +export class IUplinkProperty { + wgOrgIdRef: string; + wgPropertyIdRef: string; + name: string; + type: 'website' | 'app' | 'api' | 'other'; + access: 'private' | 'public' | 'auth'; + checkCollectionIdRefs: string[]; +} diff --git a/ts_interfaces/data/search.ts b/ts_interfaces/data/search.ts new file mode 100644 index 0000000..6a97d05 --- /dev/null +++ b/ts_interfaces/data/search.ts @@ -0,0 +1,21 @@ +export interface ISearchResult { + searchTerm: string; + targetUrl: string; + title: string; + description: string; + rank: number; +} + +/** + * special data returned by the PageRankCheck check class + */ +export interface IPageRankResult { + googleRank: number; + googleBlocked: boolean; + bingRank: number; + bingBlocked: boolean; + searchResults: { + google: ISearchResult[]; + bing: ISearchResult[]; + }; +} diff --git a/ts_interfaces/data/servicestatus.ts b/ts_interfaces/data/servicestatus.ts new file mode 100644 index 0000000..c54bf91 --- /dev/null +++ b/ts_interfaces/data/servicestatus.ts @@ -0,0 +1,64 @@ +import type { TStatusType, TStatusMode, TCheckType } from './types.js'; + +// ============================================ +// Service Status +// ============================================ + +/** + * Represents the status of a monitored service. + */ +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 + checkType?: TCheckType; + checkCollectionId?: string; + intervalMs?: number; +} + +// ============================================ +// Status History +// ============================================ + +/** + * A point in the status history timeline. + */ +export interface IStatusHistoryPoint { + timestamp: number; + status: TStatusType; + responseTime?: number; +} + +// ============================================ +// Overall Status +// ============================================ + +/** + * Aggregate status for a group of services or entire status page. + */ +export interface IOverallStatus { + status: TStatusType; + message?: string; + lastUpdated: number; +} diff --git a/ts_interfaces/data/status.ts b/ts_interfaces/data/status.ts new file mode 100644 index 0000000..ef6396b --- /dev/null +++ b/ts_interfaces/data/status.ts @@ -0,0 +1,12 @@ +import * as plugins from '../ul-interfaces.plugins.js'; + +export interface IStatus { + last90days: IDailyStatus[]; +} + +export interface IDailyStatus { + timezone: 'UTC'; + date: plugins.tsclass.general.IDate; + overallStatus: 'ok' | 'reduced' | 'outage'; + incidentRefs: string[]; +} diff --git a/ts_interfaces/data/statuspageconfig.ts b/ts_interfaces/data/statuspageconfig.ts new file mode 100644 index 0000000..dbecfd7 --- /dev/null +++ b/ts_interfaces/data/statuspageconfig.ts @@ -0,0 +1,57 @@ +import type { IOverallStatus } from './servicestatus.js'; + +// ============================================ +// Service Group +// ============================================ + +/** + * A group of related services displayed together. + */ +export interface IServiceGroup { + id: string; + name: string; + description?: string; + serviceIds: string[]; + expanded: boolean; + order?: number; +} + +// ============================================ +// Status Page Configuration +// ============================================ + +/** + * Configuration for a public status page. + */ +export interface IStatusPageConfig { + id: string; + name: string; + slug: string; + + // Branding + logoUrl?: string; + faviconUrl?: string; + primaryColor?: string; + customCss?: string; + + // Content + headerTitle: string; + headerDescription?: string; + footerText?: string; + + // Features + showHistoricalUptime: boolean; + showResponseTime: boolean; + showSubscribeButton: boolean; + showIncidentHistory: boolean; + + // Service grouping + serviceGroups: IServiceGroup[]; + + // Overall status override + overallStatus?: IOverallStatus; + + // Custom domain + customDomain?: string; + sslEnabled?: boolean; +} diff --git a/ts_interfaces/data/types.ts b/ts_interfaces/data/types.ts new file mode 100644 index 0000000..e5952e6 --- /dev/null +++ b/ts_interfaces/data/types.ts @@ -0,0 +1,63 @@ +/** + * Shared type definitions for uptime.link + */ + +// ============================================ +// Status Types +// ============================================ + +/** + * Status types for monitors/services + */ +export type TStatusType = + | 'operational' + | 'degraded' + | 'partial_outage' + | 'major_outage' + | 'maintenance' + | 'initializing' + | 'error' + | 'paused'; + +/** + * Check types (discriminant values for TCheck union) + */ +export type TCheckType = 'assumption' | 'function' | 'pwa' | 'pagerank'; + +/** + * Status mode for monitors - auto follows checks, manual is user-set + */ +export type TStatusMode = 'auto' | 'manual'; + +// ============================================ +// Incident Types +// ============================================ + +/** + * Incident severity levels + */ +export type TIncidentSeverity = 'critical' | 'major' | 'minor' | 'maintenance'; + +/** + * Incident status workflow + */ +export type TIncidentStatus = + | 'investigating' + | 'identified' + | 'monitoring' + | 'resolved' + | 'postmortem'; + +// ============================================ +// Check Result Types (used by execution) +// ============================================ + +/** + * Result status for check execution + */ +export type TCheckResultStatus = 'ok' | 'not ok' | 'timed out'; + +/** + * Last result state for a check + */ +export type TCheckLastResult = 'success' | 'failure' | 'pending'; diff --git a/ts_interfaces/index.ts b/ts_interfaces/index.ts new file mode 100644 index 0000000..9fd8621 --- /dev/null +++ b/ts_interfaces/index.ts @@ -0,0 +1,4 @@ +import * as requests from './requests/index.js'; +import * as data from './data/index.js'; + +export { requests, data }; diff --git a/ts_interfaces/requests/index.ts b/ts_interfaces/requests/index.ts new file mode 100644 index 0000000..68cd0eb --- /dev/null +++ b/ts_interfaces/requests/index.ts @@ -0,0 +1,4 @@ +export * from './requests.checks.js'; +export * from './requests.incidents.js'; +export * from './requests.snapshot.js'; +export * from './requests.status.js'; diff --git a/ts_interfaces/requests/requests.checks.ts b/ts_interfaces/requests/requests.checks.ts new file mode 100644 index 0000000..1a430a6 --- /dev/null +++ b/ts_interfaces/requests/requests.checks.ts @@ -0,0 +1,16 @@ +import type { ICheckCollection } from '../data/checkcollection.js'; +import * as plugins from '../ul-interfaces.plugins.js'; + +export interface IRequest_CheckExchange + extends plugins.typedRequestInterfaces.implementsTR< + plugins.typedRequestInterfaces.ITypedRequest, + IRequest_CheckExchange + > { + method: 'check'; + request: { + checkCollection: ICheckCollection; + }; + response: { + checkCollection: ICheckCollection; + }; +} diff --git a/ts_interfaces/requests/requests.incidents.ts b/ts_interfaces/requests/requests.incidents.ts new file mode 100644 index 0000000..1e5735a --- /dev/null +++ b/ts_interfaces/requests/requests.incidents.ts @@ -0,0 +1,17 @@ +import * as plugins from '../ul-interfaces.plugins.js'; +import * as data from '../data/index.js'; + +export interface IRequest_Incidents_Get + extends plugins.typedRequestInterfaces.implementsTR< + plugins.typedRequestInterfaces.ITypedRequest, + IRequest_Incidents_Get + > { + method: 'getIncidents'; + request: { + userToken?: string; + }; + response: { + currentIncidents: data.IIncident[]; + pastIncidents: data.IIncident[]; + }; +} diff --git a/ts_interfaces/requests/requests.snapshot.ts b/ts_interfaces/requests/requests.snapshot.ts new file mode 100644 index 0000000..aa5a6a4 --- /dev/null +++ b/ts_interfaces/requests/requests.snapshot.ts @@ -0,0 +1,18 @@ +import type { IDomainSnapshot } from '../data/domainsnapshot.js'; +import type { ILinkSnapshot } from '../data/linksnapshot.js'; +import * as plugins from '../ul-interfaces.plugins.js'; + +export interface IReq_PerformDomainSnapshot + extends plugins.typedRequestInterfaces.implementsTR< + plugins.typedRequestInterfaces.ITypedRequest, + IReq_PerformDomainSnapshot + > { + method: 'performDomainSnapshot'; + request: { + domainName: string; + }; + response: { + domainSnapshot: IDomainSnapshot; + linkSnapshot: ILinkSnapshot; + }; +} diff --git a/ts_interfaces/requests/requests.status.ts b/ts_interfaces/requests/requests.status.ts new file mode 100644 index 0000000..42b68cf --- /dev/null +++ b/ts_interfaces/requests/requests.status.ts @@ -0,0 +1,17 @@ +import * as plugins from '../ul-interfaces.plugins.js'; +import * as data from '../data/index.js'; +import type { IStatus } from '../data/status.js'; + +export interface IRequest_Status_Get + extends plugins.typedRequestInterfaces.implementsTR< + plugins.typedRequestInterfaces.ITypedRequest, + IRequest_Status_Get + > { + method: 'getStatus'; + request: { + userToken?: string; + }; + response: { + status: IStatus; + }; +} diff --git a/ts_interfaces/status.ts b/ts_interfaces/status.ts new file mode 100644 index 0000000..715f217 --- /dev/null +++ b/ts_interfaces/status.ts @@ -0,0 +1,5 @@ +export type TServiceStatus = 'up' | 'down'; + +export interface IHourlyStatus { + states: { unixTimes: number; status: TServiceStatus }; +} diff --git a/ts_interfaces/ul-interfaces.plugins.ts b/ts_interfaces/ul-interfaces.plugins.ts new file mode 100644 index 0000000..484ab7e --- /dev/null +++ b/ts_interfaces/ul-interfaces.plugins.ts @@ -0,0 +1,8 @@ +import * as typedRequestInterfaces from '@api.global/typedrequest-interfaces'; + +export { typedRequestInterfaces }; + +// tsclass scope +import * as tsclass from '@tsclass/tsclass'; + +export { tsclass };