Skip to content
Merged
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
38 changes: 38 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: CI

on:
push:
pull_request:
branches: [main]

permissions:
contents: read

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out repository
uses: actions/checkout@v4

- name: Set up Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.23

- name: Install dependencies
run: bun install --frozen-lockfile

- name: Lint
run: bun run lint

- name: Test
run: bun run test

- name: Build
run: bun run build
Binary file removed Codebase.zip
Binary file not shown.
27 changes: 10 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,29 @@ Neighbour repo: [SEBI-Compliance-Research](https://github.com/d33pm3/SEBI-Compli
**This is not** [SEBI-Compliance-Research](https://github.com/d33pm3/SEBI-Compliance-Research) (that repo researches live obligations into a 12-column workbook).
**This is not** a full-stack multi-agent platform or a live LLM pipeline.
**This is not** a filing, calendar submission, or compliance opinion.
**This is not** a complete `src/` tree on `main` — the runnable source is in `Codebase.zip`.
**This is** a self-contained repository with runnable source tracked under `src/` and `public/`.

## Where the source is
## Synthetic demo data

The **complete application source** is in [`Codebase.zip`](Codebase.zip), under:

- `1_SEBI Full Stack App/src/`
- `1_SEBI Full Stack App/public/`

There is no runnable `src/` on `main`. Extract the zip before `npm run dev`.
All company, user, filing, notice, document, system-health, and operational records in this repository are fictional synthetic demo fixtures. They must not be treated as real customer, company, regulatory, or operational information.

## Run the eval build

Requires Node.js 18+ and npm.
Requires Bun 1.2.23.

```bash
git clone https://github.com/d33pm3/Multi-agent-Full-Stack-App.git
cd Multi-agent-Full-Stack-App
unzip -o Codebase.zip
cp -a "1_SEBI Full Stack App/src/." src/
cp -a "1_SEBI Full Stack App/public/." public/
npm i
npm run dev
bun install --frozen-lockfile
bun run dev
```

After extract, `src/main.tsx` must exist. If it does not, the zip did not unpack.
Validate the same baseline used by CI:

```bash
npm test
npm run build
bun run lint
bun run test
bun run build
```

## What is not deployed
Expand Down
15 changes: 15 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,19 @@ export default tseslint.config(
"@typescript-eslint/no-unused-vars": "off",
},
},
{
files: ["src/components/ui/{command,textarea}.tsx"],
rules: {
"@typescript-eslint/no-empty-object-type": "off",
},
},
{
files: [
"src/lib/categoryExportUtils.ts",
"src/pages/{Index,KPIs,RiskAssessment}.tsx",
],
rules: {
"@typescript-eslint/no-explicit-any": "off",
},
},
);
40 changes: 40 additions & 0 deletions public/placeholder.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
User-agent: Googlebot
Allow: /

User-agent: Bingbot
Allow: /

User-agent: Twitterbot
Allow: /

User-agent: facebookexternalhit
Allow: /

User-agent: *
Allow: /
42 changes: 42 additions & 0 deletions src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}

.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}

@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}

.card {
padding: 2em;
}

.read-the-docs {
color: #888;
}
61 changes: 61 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Route, Routes } from "react-router-dom";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { Toaster } from "@/components/ui/toaster";
import { TooltipProvider } from "@/components/ui/tooltip";
import NoticeDetail from "./pages/NoticeDetail";
import Index from "./pages/Index.tsx";
import RegisterAgent from "./pages/RegisterAgent.tsx";
import RiskAssessment from "./pages/RiskAssessment.tsx";
import DocumentVault from "./pages/DocumentVault.tsx";
import ComplianceChatbot from "./pages/ComplianceChatbot.tsx";
import ComplianceAssistant from "./pages/ComplianceAssistant.tsx";
import AdminModule from "./pages/AdminModule.tsx";
import ResponseTracker from "./pages/ResponseTracker.tsx";
import TaskManager from "./pages/TaskManager.tsx";
import ComplianceTimeline from "./pages/ComplianceTimeline.tsx";
import KPIs from "./pages/KPIs.tsx";
import AgentOutputDetail from "./pages/AgentOutputDetail.tsx";
import ComplianceCalendar from "./pages/ComplianceCalendar.tsx";
import RiskActionPlan from "./pages/RiskActionPlan.tsx";
import RegisterManager from "./pages/RegisterManager.tsx";


import ComplianceItemDetail from "./pages/ComplianceItemDetail.tsx";
import NotFound from "./pages/NotFound.tsx";

const queryClient = new QueryClient();

const App = () => (
<QueryClientProvider client={queryClient}>
<TooltipProvider>
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Index />} />
<Route path="/register-agent" element={<RegisterAgent />} />
<Route path="/risk-assessment" element={<RiskAssessment />} />
<Route path="/doc-vault" element={<DocumentVault />} />
<Route path="/chatbot" element={<ComplianceChatbot />} />
<Route path="/assistant" element={<ComplianceAssistant />} />
<Route path="/notices/:noticeId" element={<NoticeDetail />} />
<Route path="/response-tracker" element={<ResponseTracker />} />
<Route path="/tasks" element={<TaskManager />} />
<Route path="/timeline" element={<ComplianceTimeline />} />
<Route path="/kpis" element={<KPIs />} />
<Route path="/agent-outputs/:kind" element={<AgentOutputDetail />} />
<Route path="/calendar" element={<ComplianceCalendar />} />
<Route path="/risk-action-plan" element={<RiskActionPlan />} />
<Route path="/register-manager" element={<RegisterManager />} />

<Route path="/compliance/:id" element={<ComplianceItemDetail />} />
<Route path="/admin" element={<AdminModule />} />
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</TooltipProvider>
</QueryClientProvider>
);

export default App;
Binary file added src/assets/ecxo-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 50 additions & 0 deletions src/components/AppHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Bell, User } from 'lucide-react';
import ecxoLogo from '@/assets/ecxo-logo.png';
import { SidebarTrigger } from '@/components/ui/sidebar';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { useComplianceStore } from '@/store/complianceStore';

interface AppHeaderProps {
title: string;
subtitle?: string;
}

export function AppHeader({ title, subtitle }: AppHeaderProps) {
const items = useComplianceStore(s => s.items);
const overdueCount = items.filter(i => i.status === 'Overdue').length;
const dueSoonCount = items.filter(i => i.status === 'Due Soon').length;
const alertCount = overdueCount + dueSoonCount;

return (
<header className="h-14 border-b border-border bg-card flex items-center justify-between px-4 flex-shrink-0">
<div className="flex items-center gap-3">
<SidebarTrigger className="text-muted-foreground hover:text-foreground" />
<div>
<h2 className="text-sm font-semibold text-foreground leading-tight">{title}</h2>
{subtitle && <p className="text-[11px] text-muted-foreground">{subtitle}</p>}
</div>
</div>

<div className="flex items-center gap-3">
<div className="hidden md:flex items-center gap-2 text-xs text-muted-foreground">
<img src={ecxoLogo} alt="deriskadvisory logo" className="h-6 w-6 rounded-full" />
<span className="font-medium">deriskadvisory</span>
</div>

<Button variant="ghost" size="icon" className="relative">
<Bell className="h-4 w-4" />
{alertCount > 0 && (
<Badge className="absolute -top-1 -right-1 h-4 min-w-4 px-1 text-[10px] bg-destructive text-destructive-foreground">
{alertCount}
</Badge>
)}
</Button>

<Button variant="ghost" size="icon">
<User className="h-4 w-4" />
</Button>
</div>
</header>
);
}
25 changes: 25 additions & 0 deletions src/components/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { SidebarProvider } from '@/components/ui/sidebar';
import { AppSidebar } from '@/components/AppSidebar';
import { AppHeader } from '@/components/AppHeader';

interface AppLayoutProps {
children: React.ReactNode;
title: string;
subtitle?: string;
}

export function AppLayout({ children, title, subtitle }: AppLayoutProps) {
return (
<SidebarProvider>
<div className="min-h-screen flex w-full">
<AppSidebar />
<div className="flex-1 flex flex-col min-w-0">
<AppHeader title={title} subtitle={subtitle} />
<main className="flex-1 overflow-auto p-4 md:p-6">
{children}
</main>
</div>
</div>
</SidebarProvider>
);
}
Loading
Loading