187 lines
9.7 KiB
Markdown
187 lines
9.7 KiB
Markdown
# Channel Partner Portal & Secure Asset Management
|
|
|
|
## Enterprise Architecture & Implementation Guide
|
|
|
|
This guide details the complete system architecture, visual design specs, existing code evidence, and future implementation roadmap for the secure, multi-tenant Channel Partner Onboarding Platform.
|
|
|
|
---
|
|
|
|
## 📖 Table of Contents
|
|
|
|
1. [Project Overview & Vision](#1-project-overview--vision)
|
|
2. [Database Schema (Prisma Models)](#2-database-schema-prisma-models)
|
|
3. [Completed Implementations & Code Evidence](#3-completed-implementations--code-evidence)
|
|
4. [MinIO S3-Compatible Storage Migration Guide](#4-minio-s3-compatible-storage-migration-guide)
|
|
5. [Future Development Roadmap & Milestones](#5-future-development-roadmap--milestones)
|
|
|
|
---
|
|
|
|
## 1. Project Overview & Vision
|
|
|
|
The Channel Partner Portal is a premium SaaS onboarding and secure document hub designed to look like modern workspaces (Notion/Linear) rather than standard tabular dashboards.
|
|
|
|
### Core Product Pillars
|
|
|
|
* **Secure Document Hub**: Multi-format document rendering engine with sandbox protections.
|
|
* **Role-Based Access Control (RBAC)**: Fine-grained permissions defining view-only vs. downloadable scopes.
|
|
* **Dynamic Sharing Scopes**: Direct share targeting to specific organizations or filtered to singular organization users.
|
|
* **Onboarding legal flow**: Gated portal requiring formal signature and tracking for NDA/MSA documents.
|
|
|
|
---
|
|
|
|
## 2. Database Schema (Prisma Models)
|
|
|
|
Our active PostgreSQL schema in `/Channel-Backend/prisma/schema.prisma` is designed around multi-tenancy and audit compliance:
|
|
|
|
| Model | Purpose | Key Relations |
|
|
| :------------------ | :--------------------------------------- | :------------------------------------------------------------------- |
|
|
| `Organization` | Tenant container | Has many`User` & `SharedAsset` |
|
|
| `User` | Authenticated users (Admin/Partner) | Belongs to`Organization`, Has many `DownloadRequest` |
|
|
| `Asset` | Physical/URL resource registry | Belongs to`Folder`, Has many `SharedAsset` & `DownloadRequest` |
|
|
| `SharedAsset` | Connects assets to organizations/users | Unique on`[assetId, organizationId, userId]` |
|
|
| `DownloadRequest` | Pending/Approved requests for download | Unique on`[assetId, userId]` |
|
|
| `LegalDocument` | Repository of NDA/MSA text templates | Versioned, Has many`LegalAcceptance` |
|
|
| `LegalAcceptance` | Tracks IP/hashes of accepted legal forms | Connected to`User` and `LegalDocument` |
|
|
| `AuditLog` | Immutable event tracker | Linked to actor (`User`) |
|
|
|
|
---
|
|
|
|
## 3. Completed Implementations & Code Evidence
|
|
|
|
Here is the exact code evidence showing which files and configuration settings run the current production-ready portal features.
|
|
|
|
### A. Backend security & CSP Configuration
|
|
|
|
We modified **[Channel-Backend/src/app.ts](file:///home/tech4biz/work/channel-partner/Tech4biz-channel/Channel-Backend/src/app.ts#L18-L30)** to support secure document embedding inside frontend iframes without exposing vulnerabilities:
|
|
|
|
* **Disabled Frameguard**: Removed default `X-Frame-Options: SAMEORIGIN` block.
|
|
* **Custom Content Security Policy**: Added `Content-Security-Policy` with the `frame-ancestors` directive allowlisting `http://localhost:5173` and `http://localhost:5000` to satisfy modern Chrome iframe sandbox checks.
|
|
* **TypeScript Safety**: Avoided default fallback blockers using `dangerouslyDisableDefaultSrc` and `useDefaults: false`.
|
|
|
|
```typescript
|
|
app.use(helmet({
|
|
crossOriginResourcePolicy: { policy: "cross-origin" },
|
|
contentSecurityPolicy: {
|
|
useDefaults: false,
|
|
directives: {
|
|
"default-src": helmet.contentSecurityPolicy.dangerouslyDisableDefaultSrc,
|
|
"frame-ancestors": ["'self'", "http://localhost:5173", "http://localhost:5000"],
|
|
},
|
|
},
|
|
frameguard: false,
|
|
}));
|
|
```
|
|
|
|
### B. Expandable Preview Modal & Multi-Engine Document Reader
|
|
|
|
We overhauled the modal system in **[Channel-Frontend/src/pages/AssetsPage.tsx](file:///home/tech4biz/work/channel-partner/Tech4biz-channel/Channel-Frontend/src/pages/AssetsPage.tsx#L1250-L1356)** to support multi-format previews:
|
|
|
|
* **Expandable Viewport Layout**: Added a Maximize/Minimize toggle button in the modal header. Maximizing updates the classes to `w-[96vw] h-[92vh] max-w-none` to prevent layout clipping and display long documents natively.
|
|
* **GitHub Repository Markdown Fetcher**: Added a regex parser (`getGithubRawUrl`) and hook to automatically extract the repository name, fetch the `README.md` raw file in the background, and output the text directly inside a clean, scrollable Inter-font document reader.
|
|
* **Office Online Document Preview**: Embedded a Microsoft Office Web Viewer wrapper for PowerPoint, Excel, and Word files, with a clean local-mode notice for developers working on `localhost` endpoints.
|
|
* **Secure Image/PDF Viewer**: Uses the standard PDF frame and constrained image container (`max-h-full object-contain`).
|
|
|
|
### C. Access Control and Protected Links
|
|
|
|
* **Removed Direct Links**: Removed the "Open Native Viewer" button to prevent users from bypassing access controls and downloading documents directly.
|
|
* **Protected Website URLs**: Blocked the "Open Link in New Tab" action for URL-based assets. It is now hidden behind the `isDownloadable` or approved download request validation, prompting unapproved users to ask for access first.
|
|
* **Download request reset**: Client request states are fully synchronized. When an admin rejects a download request, the frontend allows the user to re-submit a request by resetting the request status back to `PENDING` in the database.
|
|
|
|
---
|
|
|
|
## 4. MinIO S3-Compatible Storage Migration Guide
|
|
|
|
Currently, files are uploaded to `/uploads` on the backend's local directory. To support scaling, high-performance CDN setups, and enterprise security, we will migrate the static storage engine to **MinIO** (an open-source S3-compatible object storage).
|
|
|
|
### A. MinIO Deployment Setup (Docker)
|
|
|
|
Add the MinIO service to your local developer containers or run it in the background:
|
|
|
|
```bash
|
|
docker run -d \
|
|
-p 9000:9000 \
|
|
-p 9001:9001 \
|
|
--name minio-storage \
|
|
-e "MINIO_ROOT_USER=admin" \
|
|
-e "MINIO_ROOT_PASSWORD=SuperSecretPassword123" \
|
|
minio/minio server /data --console-address ":9001"
|
|
```
|
|
|
|
Log in to `http://localhost:9001` and create a private bucket named `secure-assets`.
|
|
|
|
### B. Backend Node SDK Integration
|
|
|
|
1. Install AWS S3 SDK packages:
|
|
```bash
|
|
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner multer-s3
|
|
```
|
|
2. Create an S3 configuration client (`/src/utils/s3.ts`):
|
|
```typescript
|
|
import { S3Client } from "@aws-sdk/client-s3";
|
|
|
|
export const s3Client = new S3Client({
|
|
endpoint: process.env.MINIO_ENDPOINT || "http://localhost:9000",
|
|
region: "us-east-1", // MinIO defaults
|
|
credentials: {
|
|
accessKeyId: process.env.MINIO_ACCESS_KEY || "admin",
|
|
secretAccessKey: process.env.MINIO_SECRET_KEY || "SuperSecretPassword123",
|
|
},
|
|
forcePathStyle: true, // Crucial for MinIO path style endpoints
|
|
});
|
|
```
|
|
|
|
### C. Securing Pre-Signed Preview URLs
|
|
|
|
To prevent unauthorized users from sharing document links, the files inside the MinIO bucket must remain **private**.
|
|
|
|
When a user opens the preview modal:
|
|
|
|
1. The frontend requests a temporary view link from the backend.
|
|
2. The backend generates a **pre-signed URL** that expires in **5 minutes**:
|
|
```typescript
|
|
import { GetObjectCommand } from "@aws-sdk/client-s3";
|
|
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
|
|
import { s3Client } from "./s3";
|
|
|
|
export const generateAssetPreviewUrl = async (fileKey: string): Promise<string> => {
|
|
const command = new GetObjectCommand({
|
|
Bucket: "secure-assets",
|
|
Key: fileKey,
|
|
});
|
|
|
|
// Generates a link that becomes useless after 300 seconds
|
|
return await getSignedUrl(s3Client, command, { expiresIn: 300 });
|
|
};
|
|
```
|
|
3. The frontend renders this temporary link inside the `<iframe>`. Even if the client extracts the URL from source, it will expire and become invalid shortly after.
|
|
|
|
---
|
|
|
|
## 5. Future Development Roadmap & Milestones
|
|
|
|
To finish the product and prepare it for production release, follow these step-by-step milestones.
|
|
|
|
### Milestone 1: MinIO Storage Migration
|
|
|
|
- [ ] Install S3 SDK on the backend.
|
|
- [ ] Replace file write helper in `asset.controller.ts` with S3 uploads using `PutObjectCommand`.
|
|
- [ ] Implement an endpoint on the backend (`/api/v1/assets/:id/preview`) to return a short-term pre-signed URL for document iframes.
|
|
|
|
### Milestone 2: Gated Legal Sign-off (NDA & MSA)
|
|
|
|
- [ ] Create a `LegalAgreementsModal` on the frontend that displays the active `LegalDocument` of type `NDA` or `MSA`.
|
|
- [ ] If a user's `onboardingStatus` is `PENDING_ONBOARDING`, block dashboard navigation and display the modal forcing them to accept.
|
|
- [ ] Create backend controllers to record acceptances with actor ID, IP address, and cryptographic hashes in the `LegalAcceptance` table.
|
|
|
|
### Milestone 3: Nested Folders & Bulk Operations
|
|
|
|
- [ ] Update the assets sidebar to display the nested `Folder` tree structure.
|
|
- [ ] Implement bulk share/revoke controllers that let admins select multiple assets and assign them to an entire organization or individual users in a single operation.
|
|
|
|
### Milestone 4: Partner Activity Timeline & Audit Logs
|
|
|
|
- [ ] Hook the `AuditLog` database table into all controller actions.
|
|
- [ ] Display an interactive activity timeline on the Admin dashboard showing:
|
|
- *Who downloaded what file and when.*
|
|
- *Organization onboardings and pending request queues.*
|