feat(opsserver,web): replace the Angular UI and REST management layer with a TypedRequest-based ops server and bundled web frontend

This commit is contained in:
2026-03-20 16:43:44 +00:00
parent 0fc74ff995
commit d4f758ce0f
159 changed files with 12465 additions and 14861 deletions

View File

@@ -0,0 +1,80 @@
// ============================================================================
// Admin Data Types
// ============================================================================
import type { TAuthProviderStatus, TAuthProviderType } from './auth.ts';
export interface IOAuthConfig {
clientId: string;
clientSecretEncrypted: string;
issuer: string;
authorizationUrl?: string;
tokenUrl?: string;
userInfoUrl?: string;
scopes: string[];
callbackUrl: string;
}
export interface ILdapConfig {
serverUrl: string;
bindDn: string;
bindPasswordEncrypted: string;
baseDn: string;
userSearchFilter: string;
tlsEnabled: boolean;
tlsCaCert?: string;
}
export interface IAttributeMapping {
email: string;
username: string;
displayName: string;
avatarUrl?: string;
groups?: string;
}
export interface IProvisioningSettings {
jitEnabled: boolean;
autoLinkByEmail: boolean;
allowedEmailDomains?: string[];
}
export interface IAuthProvider {
id: string;
name: string;
displayName: string;
type: TAuthProviderType;
status: TAuthProviderStatus;
priority: number;
oauthConfig?: IOAuthConfig;
ldapConfig?: ILdapConfig;
attributeMapping: IAttributeMapping;
provisioning: IProvisioningSettings;
createdAt: string;
updatedAt: string;
createdById: string;
lastTestedAt?: string;
lastTestResult?: 'success' | 'failure';
lastTestError?: string;
}
export interface IPlatformAuthSettings {
localAuthEnabled: boolean;
allowUserRegistration: boolean;
sessionDurationMinutes: number;
defaultProviderId?: string;
}
export interface IPlatformSettings {
id: string;
auth: IPlatformAuthSettings;
updatedAt: string;
updatedById?: string;
}
export interface IConnectionTestResult {
success: boolean;
latencyMs: number;
serverInfo?: Record<string, unknown>;
error?: string;
}

View File

@@ -0,0 +1,79 @@
// ============================================================================
// Audit Data Types
// ============================================================================
export type TAuditAction =
| 'AUTH_LOGIN'
| 'AUTH_LOGOUT'
| 'AUTH_FAILED'
| 'AUTH_MFA_ENABLED'
| 'AUTH_MFA_DISABLED'
| 'AUTH_PASSWORD_CHANGED'
| 'AUTH_PASSWORD_RESET'
| 'TOKEN_CREATED'
| 'TOKEN_USED'
| 'TOKEN_REVOKED'
| 'TOKEN_EXPIRED'
| 'USER_CREATED'
| 'USER_UPDATED'
| 'USER_DELETED'
| 'USER_SUSPENDED'
| 'USER_ACTIVATED'
| 'ORG_CREATED'
| 'ORG_UPDATED'
| 'ORG_DELETED'
| 'ORG_MEMBER_ADDED'
| 'ORG_MEMBER_REMOVED'
| 'ORG_MEMBER_ROLE_CHANGED'
| 'TEAM_CREATED'
| 'TEAM_UPDATED'
| 'TEAM_DELETED'
| 'TEAM_MEMBER_ADDED'
| 'TEAM_MEMBER_REMOVED'
| 'REPO_CREATED'
| 'REPO_UPDATED'
| 'REPO_DELETED'
| 'REPO_VISIBILITY_CHANGED'
| 'REPO_PERMISSION_GRANTED'
| 'REPO_PERMISSION_REVOKED'
| 'PACKAGE_PUSHED'
| 'PACKAGE_PULLED'
| 'PACKAGE_DELETED'
| 'PACKAGE_DEPRECATED'
| 'AUTH_PROVIDER_CREATED'
| 'AUTH_PROVIDER_UPDATED'
| 'AUTH_PROVIDER_DELETED'
| 'AUTH_PROVIDER_TESTED'
| 'PLATFORM_SETTINGS_UPDATED'
| 'SECURITY_SCAN_COMPLETED'
| 'SECURITY_VULNERABILITY_FOUND'
| 'SECURITY_IP_BLOCKED'
| 'SECURITY_RATE_LIMITED';
export type TAuditResourceType =
| 'user'
| 'organization'
| 'team'
| 'repository'
| 'package'
| 'api_token'
| 'session'
| 'auth_provider'
| 'platform_settings'
| 'system';
export interface IAuditEntry {
id: string;
actorId?: string;
actorType: 'user' | 'api_token' | 'system' | 'anonymous';
action: TAuditAction;
resourceType: TAuditResourceType;
resourceId?: string;
resourceName?: string;
organizationId?: string;
repositoryId?: string;
success: boolean;
errorCode?: string;
timestamp: string;
metadata: Record<string, unknown>;
}

View File

@@ -0,0 +1,49 @@
// ============================================================================
// Auth Data Types
// ============================================================================
export type TUserStatus = 'active' | 'suspended' | 'pending_verification';
export interface IIdentity {
jwt: string;
refreshJwt: string;
userId: string;
email: string;
username: string;
displayName: string;
isSystemAdmin: boolean;
expiresAt: number;
sessionId: string;
}
export interface IUser {
id: string;
email: string;
username: string;
displayName: string;
avatarUrl?: string;
isSystemAdmin: boolean;
isActive: boolean;
createdAt: string;
lastLoginAt?: string;
}
export interface ISession {
id: string;
userId: string;
userAgent: string;
ipAddress: string;
isValid: boolean;
lastActivityAt: string;
createdAt: string;
}
export interface IPublicAuthProvider {
id: string;
name: string;
displayName: string;
type: TAuthProviderType;
}
export type TAuthProviderType = 'oidc' | 'ldap';
export type TAuthProviderStatus = 'active' | 'disabled' | 'testing';

View File

@@ -0,0 +1,7 @@
export * from './auth.ts';
export * from './organization.ts';
export * from './repository.ts';
export * from './package.ts';
export * from './token.ts';
export * from './audit.ts';
export * from './admin.ts';

View File

@@ -0,0 +1,48 @@
// ============================================================================
// Organization Data Types
// ============================================================================
export type TOrganizationPlan = 'free' | 'team' | 'enterprise';
export type TOrganizationRole = 'owner' | 'admin' | 'member';
export interface IOrganization {
id: string;
name: string;
displayName: string;
description?: string;
avatarUrl?: string;
website?: string;
isPublic: boolean;
memberCount: number;
plan: TOrganizationPlan;
usedStorageBytes: number;
storageQuotaBytes: number;
createdAt: string;
}
export interface IOrganizationDetail extends IOrganization {
settings?: IOrganizationSettings;
}
export interface IOrganizationSettings {
requireMfa: boolean;
allowPublicRepositories: boolean;
defaultRepositoryVisibility: TRepositoryVisibility;
allowedProtocols: TRegistryProtocol[];
}
export interface IOrganizationMember {
userId: string;
role: TOrganizationRole;
addedAt: string;
user: {
username: string;
displayName: string;
avatarUrl?: string;
} | null;
}
// Re-export types used by settings
import type { TRepositoryVisibility } from './repository.ts';
import type { TRegistryProtocol } from './package.ts';
export type { TRegistryProtocol, TRepositoryVisibility };

View File

@@ -0,0 +1,53 @@
// ============================================================================
// Package Data Types
// ============================================================================
export type TRegistryProtocol =
| 'oci'
| 'npm'
| 'maven'
| 'cargo'
| 'composer'
| 'pypi'
| 'rubygems';
export interface IPackage {
id: string;
name: string;
description?: string;
protocol: TRegistryProtocol;
organizationId: string;
repositoryId: string;
latestVersion?: string;
isPrivate: boolean;
downloadCount: number;
starCount: number;
storageBytes: number;
updatedAt: string;
createdAt: string;
}
export interface IPackageDetail extends IPackage {
distTags: Record<string, string>;
versions: string[];
}
export interface IPackageVersion {
version: string;
publishedAt: string;
size: number;
downloads: number;
checksum?: {
sha256?: string;
sha512?: string;
md5?: string;
};
}
export interface IPackageSearchParams {
query?: string;
protocol?: TRegistryProtocol;
organizationId?: string;
limit?: number;
offset?: number;
}

View File

@@ -0,0 +1,22 @@
// ============================================================================
// Repository Data Types
// ============================================================================
import type { TRegistryProtocol } from './package.ts';
export type TRepositoryVisibility = 'public' | 'private' | 'internal';
export type TRepositoryRole = 'admin' | 'maintainer' | 'developer' | 'reader';
export interface IRepository {
id: string;
organizationId: string;
name: string;
description?: string;
protocol: TRegistryProtocol;
visibility: TRepositoryVisibility;
isPublic: boolean;
packageCount: number;
storageBytes: number;
downloadCount: number;
createdAt: string;
}

View File

@@ -0,0 +1,33 @@
// ============================================================================
// Token Data Types
// ============================================================================
import type { TRegistryProtocol } from './package.ts';
export type TTokenAction = 'read' | 'write' | 'delete' | '*';
export interface ITokenScope {
protocol: TRegistryProtocol | '*';
organizationId?: string;
repositoryId?: string;
actions: TTokenAction[];
}
export interface IToken {
id: string;
name: string;
tokenPrefix: string;
protocols: TRegistryProtocol[];
scopes: ITokenScope[];
organizationId?: string;
createdById?: string;
expiresAt?: string;
lastUsedAt?: string;
usageCount: number;
createdAt: string;
}
export interface ITokenCreateResult extends IToken {
token: string;
warning: string;
}