feat: implement naming convention, deployment automation, and infrastructure updates

- Add comprehensive naming convention (provider-region-resource-env-purpose)
- Implement Terraform locals for centralized naming
- Update all Terraform resources to use new naming convention
- Create deployment automation framework (18 phase scripts)
- Add Azure setup scripts (provider registration, quota checks)
- Update deployment scripts config with naming functions
- Create complete deployment documentation (guide, steps, quick reference)
- Add frontend portal implementations (public and internal)
- Add UI component library (18 components)
- Enhance Entra VerifiedID integration with file utilities
- Add API client package for all services
- Create comprehensive documentation (naming, deployment, next steps)

Infrastructure:
- Resource groups, storage accounts with new naming
- Terraform configuration updates
- Outputs with naming convention examples

Deployment:
- Automated deployment scripts for all 15 phases
- State management and logging
- Error handling and validation

Documentation:
- Naming convention guide and implementation summary
- Complete deployment guide (296 steps)
- Next steps and quick start guides
- Azure prerequisites and setup completion docs

Note: ESLint warnings present - will be addressed in follow-up commit
This commit is contained in:
defiQUG
2025-11-12 08:22:51 -08:00
parent 9e46f3f316
commit 8649ad4124
136 changed files with 17251 additions and 147 deletions

View File

@@ -0,0 +1,126 @@
'use client';
import React from 'react';
// Simple auth store without external dependencies
// In production, this would use Zustand or a proper auth library
interface AuthUser {
id: string;
email?: string;
name?: string;
did?: string;
roles?: string[];
accessToken?: string;
refreshToken?: string;
}
interface AuthState {
user: AuthUser | null;
isAuthenticated: boolean;
isLoading: boolean;
login: (user: AuthUser) => void;
logout: () => void;
setUser: (user: AuthUser | null) => void;
}
// Simple in-memory store with localStorage persistence
class AuthStore {
private state: AuthState = {
user: null,
isAuthenticated: false,
isLoading: false,
login: () => {},
logout: () => {},
setUser: () => {},
};
private listeners: Set<(state: AuthState) => void> = new Set();
constructor() {
this.loadFromStorage();
}
private loadFromStorage() {
if (typeof window === 'undefined') return;
try {
const stored = localStorage.getItem('auth-storage');
if (stored) {
const parsed = JSON.parse(stored);
this.state.user = parsed.user || null;
this.state.isAuthenticated = !!this.state.user;
}
} catch {
// Ignore parse errors
}
}
private saveToStorage() {
if (typeof window === 'undefined') return;
try {
localStorage.setItem('auth-storage', JSON.stringify({ user: this.state.user }));
} catch {
// Ignore storage errors
}
}
private notify() {
this.listeners.forEach((listener) => listener(this.state));
}
subscribe(listener: (state: AuthState) => void) {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
}
getState() {
return this.state;
}
setState(updates: Partial<AuthState>) {
this.state = { ...this.state, ...updates };
this.saveToStorage();
this.notify();
}
}
const authStore = typeof window !== 'undefined' ? new AuthStore() : null;
// React hook to use auth state
export function useAuth(): AuthState {
const [state, setState] = React.useState<AuthState>(
authStore?.getState() || {
user: null,
isAuthenticated: false,
isLoading: false,
login: () => {},
logout: () => {},
setUser: () => {},
}
);
React.useEffect(() => {
if (!authStore) return;
const unsubscribe = authStore.subscribe(setState);
return unsubscribe;
}, []);
return {
...state,
login: (user: AuthUser) => {
authStore?.setState({ user, isAuthenticated: true });
if (user.accessToken) {
localStorage.setItem('auth_token', user.accessToken);
}
},
logout: () => {
authStore?.setState({ user: null, isAuthenticated: false });
localStorage.removeItem('auth_token');
},
setUser: (user: AuthUser | null) => {
authStore?.setState({ user, isAuthenticated: !!user });
},
};
}

View File

@@ -0,0 +1,27 @@
'use client';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ReactNode, useState } from 'react';
import { ToastProvider } from '@the-order/ui';
export function Providers({ children }: { children: ReactNode }) {
const [queryClient] = useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 60 * 1000, // 1 minute
refetchOnWindowFocus: false,
retry: 1,
},
},
})
);
return (
<QueryClientProvider client={queryClient}>
<ToastProvider>{children}</ToastProvider>
</QueryClientProvider>
);
}