Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 3 additions & 13 deletions app/backend/src/contracts/contract-registry.service.unit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { ContractChangeWebhookService } from './contract-change-webhook.service'
import {
ContractChangeWebhookDispatcher,
} from './contract-change-webhook.dispatcher';
import { DeploymentValidationService } from './deployment-validation.service';


describe('ContractRegistryService', () => {
let service: ContractRegistryService;
Expand All @@ -18,7 +18,7 @@ describe('ContractRegistryService', () => {
let mockEventEmitter: jest.Mocked<EventEmitter2>;
let mockContractChangeWebhookService: jest.Mocked<Partial<ContractChangeWebhookService>>;
let mockWebhookDispatcher: jest.Mocked<Partial<ContractChangeWebhookDispatcher>>;
let mockDeploymentValidationService: jest.Mocked<Partial<DeploymentValidationService>>;


beforeEach(() => {
const mockClient = {
Expand Down Expand Up @@ -58,13 +58,7 @@ describe('ContractRegistryService', () => {
dispatch: jest.fn().mockResolvedValue([]),
} as unknown as jest.Mocked<Partial<ContractChangeWebhookDispatcher>>;

mockDeploymentValidationService = {
validateLedgerSequence: jest.fn(),
validateNetworkBinding: jest.fn(),
validateDeploymentManifest: jest.fn(),
checkNetworkCompatibility: jest.fn(),
getExpectedPassphrase: jest.fn(),
} as unknown as jest.Mocked<Partial<DeploymentValidationService>>;


service = new ContractRegistryService(
mockSupabaseService as unknown as SupabaseService,
Expand All @@ -73,7 +67,6 @@ describe('ContractRegistryService', () => {
mockEventEmitter,
mockContractChangeWebhookService as unknown as ContractChangeWebhookService,
mockWebhookDispatcher as unknown as ContractChangeWebhookDispatcher,
mockDeploymentValidationService as unknown as DeploymentValidationService,
);
});

Expand Down Expand Up @@ -259,7 +252,6 @@ describe('ContractRegistryService', () => {
mockEventEmitter,
mockContractChangeWebhookService as unknown as ContractChangeWebhookService,
mockWebhookDispatcher as unknown as ContractChangeWebhookDispatcher,
mockDeploymentValidationService as unknown as DeploymentValidationService,
);

const result = await service.finalizeDualRead('quickex');
Expand Down Expand Up @@ -298,7 +290,6 @@ describe('ContractRegistryService', () => {
mockEventEmitter,
mockContractChangeWebhookService as unknown as ContractChangeWebhookService,
mockWebhookDispatcher as unknown as ContractChangeWebhookDispatcher,
mockDeploymentValidationService as unknown as DeploymentValidationService,
);

await expect(service.finalizeDualRead('missing')).rejects.toThrow(NotFoundException);
Expand Down Expand Up @@ -348,7 +339,6 @@ describe('ContractRegistryService', () => {
mockEventEmitter,
mockContractChangeWebhookService as unknown as ContractChangeWebhookService,
mockWebhookDispatcher as unknown as ContractChangeWebhookDispatcher,
mockDeploymentValidationService as unknown as DeploymentValidationService,
);

await expect(service.finalizeDualRead('quickex')).rejects.toThrow(BadRequestException);
Expand Down
59 changes: 55 additions & 4 deletions app/frontend/src/app/admin/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,66 @@
"use client";

import { useState } from "react";
import { FeatureFlags } from "@/components/admin/FeatureFlags";
import { SystemHealth } from "@/components/admin/SystemHealth";
import { AuditLogs } from "@/components/admin/AuditLogs";
import { TestnetHealthConsole } from "@/components/admin/TestnetHealthConsole";
import { Activity, FileText, Shield, Stethoscope } from "lucide-react";

Check warning on line 8 in app/frontend/src/app/admin/page.tsx

View workflow job for this annotation

GitHub Actions / Lint and Type Check

'Activity' is defined but never used

export default function AdminPage() {
const [activeTab, setActiveTab] = useState<"testnet" | "system" | "audit">("testnet");

return (
<div className="max-w-6xl mx-auto space-y-6">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<FeatureFlags />
<SystemHealth />
{/* Admin Tab Navigation */}
<div className="flex items-center gap-2 border-b border-border pb-3">
<button
onClick={() => setActiveTab("testnet")}
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-colors ${
activeTab === "testnet"
? "bg-brand text-brand-foreground shadow-xs"
: "text-subtle hover:bg-surface hover:text-foreground"
}`}
>
<Stethoscope className="h-4 w-4" />
Testnet Health Console
</button>
<button
onClick={() => setActiveTab("system")}
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-colors ${
activeTab === "system"
? "bg-brand text-brand-foreground shadow-xs"
: "text-subtle hover:bg-surface hover:text-foreground"
}`}
>
<Shield className="h-4 w-4" />
Safety & System Controls
</button>
<button
onClick={() => setActiveTab("audit")}
className={`inline-flex items-center gap-2 px-4 py-2 rounded-lg text-sm font-semibold transition-colors ${
activeTab === "audit"
? "bg-brand text-brand-foreground shadow-xs"
: "text-subtle hover:bg-surface hover:text-foreground"
}`}
>
<FileText className="h-4 w-4" />
Audit Logs
</button>
</div>
<AuditLogs />

{/* Tab Content */}
{activeTab === "testnet" && <TestnetHealthConsole />}

{activeTab === "system" && (
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<FeatureFlags />
<SystemHealth />
</div>
)}

{activeTab === "audit" && <AuditLogs />}
</div>
);
}

Loading
Loading