OPC # 0001: Extract OPC into standalone repo

This commit is contained in:
amadzarak
2026-04-25 17:26:42 -04:00
commit 42383bdc03
170 changed files with 21365 additions and 0 deletions
@@ -0,0 +1,82 @@
import { useEffect } from 'react';
import type { ProvisioningRequest, TenantEnvironment, TenantTier } from '../../types/provisioning';
interface Props {
signalParent: (state: { isValid: boolean }) => void;
data: ProvisioningRequest;
onChange: (updated: Partial<ProvisioningRequest>) => void;
}
const ENVIRONMENTS: { value: TenantEnvironment; label: string; description: string }[] = [
{ value: 'fdev', label: 'Dev (fdev)', description: 'Feature development - fast provisioning, no production data.' },
{ value: 'uat', label: 'UAT', description: 'User acceptance testing - mirrors production configuration.' },
{ value: 'prod', label: 'Production', description: 'Live production environment. Full isolation enforced.' },
];
const TIERS: { value: TenantTier; label: string; description: string; badge: string }[] = [
{
value: 'Shared',
label: 'Shared',
badge: 'Standard',
description: 'Shared Keycloak, Vault, Postgres and MinIO. Isolated by realm, namespace and bucket.',
},
{
value: 'Isolated',
label: 'Isolated',
badge: 'Professional',
description: 'Shared Keycloak and Vault, but a dedicated Postgres container and MinIO bucket per tenant.',
},
{
value: 'Dedicated',
label: 'Dedicated',
badge: 'Enterprise',
description: 'Fully dedicated Keycloak, Vault, Postgres and MinIO containers for complete hard isolation.',
},
];
export default function DeploymentConfigStep({ signalParent, data, onChange }: Props) {
useEffect(() => {
signalParent({ isValid: !!data.tier && !!data.environment });
}, [data.tier, data.environment, signalParent]);
return (
<div className="wizard-step">
<p className="step-description">Choose the deployment environment and infrastructure isolation tier.</p>
<h4 style={{ marginBottom: '0.5rem' }}>Environment</h4>
<div className="tier-cards" style={{ marginBottom: '1.5rem' }}>
{ENVIRONMENTS.map((env) => (
<button
key={env.value}
type="button"
className={`tier-card${data.environment === env.value ? ' selected' : ''}`}
onClick={() => onChange({ environment: env.value })}
>
<div className="tier-card-header">
<span className="tier-card-label">{env.label}</span>
</div>
<p className="tier-card-description">{env.description}</p>
</button>
))}
</div>
<h4 style={{ marginBottom: '0.5rem' }}>Isolation Tier</h4>
<div className="tier-cards">
{TIERS.map((tier) => (
<button
key={tier.value}
type="button"
className={`tier-card${data.tier === tier.value ? ' selected' : ''}`}
onClick={() => onChange({ tier: tier.value })}
>
<div className="tier-card-header">
<span className="tier-card-label">{tier.label}</span>
<span className={`tier-card-badge tier-badge-${tier.value.toLowerCase()}`}>{tier.badge}</span>
</div>
<p className="tier-card-description">{tier.description}</p>
</button>
))}
</div>
</div>
);
}