Docs: Untrack documentation markdown files and add them to gitignore
This commit is contained in:
parent
643bb1ce68
commit
5254e347a8
9
.gitignore
vendored
9
.gitignore
vendored
@ -28,4 +28,11 @@ uploads/*
|
||||
.github/*
|
||||
.next/*
|
||||
.env.local
|
||||
.vite/*
|
||||
.vite/*
|
||||
|
||||
# Developer Documentation
|
||||
/rules.md
|
||||
/memory.md
|
||||
/phases.md
|
||||
/architecture.md
|
||||
/Guide.md
|
||||
186
Guide.md
186
Guide.md
@ -1,186 +0,0 @@
|
||||
# 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.*
|
||||
@ -1,72 +0,0 @@
|
||||
# System Architecture
|
||||
|
||||
This document details the system design, relational database models, folder structure, API routing, and security measures of the Tech4Biz Channel Partner Portal.
|
||||
|
||||
---
|
||||
|
||||
## 1. Directory Structure
|
||||
|
||||
The project is structured as a monorepo containing distinct frontend and backend directories:
|
||||
* **`Channel-Frontend/`**: Vite + React + TypeScript web application.
|
||||
* **`Channel-Backend/`**: Node.js + Express + TypeScript API server using Prisma ORM.
|
||||
* **`minio-seed/`**: Repository seed files uploaded to the private S3 bucket on initialization.
|
||||
|
||||
---
|
||||
|
||||
## 2. Database Design (Prisma PostgreSQL Schema)
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
Organization ||--o{ User : contains
|
||||
Organization ||--o{ SharedAsset : has
|
||||
User ||--o{ LegalAcceptance : signs
|
||||
User ||--o{ AuditLog : acts
|
||||
User ||--o{ SharedAsset : has
|
||||
User ||--o{ DownloadRequest : makes
|
||||
Asset ||--o{ SharedAsset : shared
|
||||
Asset ||--o{ DownloadRequest : requested
|
||||
Folder ||--o{ Asset : contains
|
||||
LegalDocument ||--o{ LegalAcceptance : tracks
|
||||
AssetGroup }|--|{ Asset : groups
|
||||
```
|
||||
|
||||
### Models Summary
|
||||
* **`Organization`**: Tenant containers mapping partner companies.
|
||||
* **`User`**: Admin and Partner users. Supports onboarding status (`PENDING_ONBOARDING`, `APPROVED`, etc.), multi-factor authentication configurations (`mfaEnabled`, `mfaSecret`), and legal document associations (`assignedNdaId`, `assignedMsaId`).
|
||||
* **`Asset`**: Physical document files, external web URLs, and Case Studies.
|
||||
* **`SharedAsset`**: Connects assets to organizations or individual users to restrict visibility.
|
||||
* **`DownloadRequest`**: Tracks approvals for un-downloadable assets.
|
||||
* **`Folder`**: Hierarchy container for assets.
|
||||
* **`LegalDocument`**: NDA / MSA legal templates versioned by admins.
|
||||
* **`LegalAcceptance`**: Cryptographic evidence of legal sign-off (contains signer IP, signature hash, and base64 signature images).
|
||||
* **`AuditLog`**: Compliance tracking logs.
|
||||
* **`BlogPost`**: Internal blog CMS posts.
|
||||
* **`AssetGroup`**: Dynamic tagging groups for catalog organization.
|
||||
|
||||
---
|
||||
|
||||
## 3. Storage Architecture (MinIO Private S3)
|
||||
|
||||
To ensure secure, scalable, and isolated asset delivery, files are hosted in a private **MinIO** S3 bucket:
|
||||
* **Upload Pipeline**: Express backend receives multipart file uploads using `multer`, uploads the buffer directly to MinIO using `@aws-sdk/client-s3`, and stores a `/uploads/filename` relative URL path in the Postgres `Asset` table.
|
||||
* **Pre-Signed URLs**: Asset URLs are **never public**. When rendering or downloading files, the backend generates short-lived, pre-signed S3 URLs (expiring in 5 minutes) via `@aws-sdk/s3-request-presigner`.
|
||||
* **Deletion Lifecycle**: When deleting an asset database record, `AssetService` intercepts the URL, detects S3 relative paths, and issues a `DeleteObjectCommand` to permanently clean up the physical file from the storage bucket.
|
||||
|
||||
---
|
||||
|
||||
## 4. Document Rendering Pipeline
|
||||
|
||||
To ensure high-fidelity previews without exposing documents to third-party services:
|
||||
* **PDF Previews**: Rendered natively in the browser via PDF.js on a hidden `<canvas>`, exporting a high-performance Base64 JPEG URL.
|
||||
* **Word Documents (`.docx`)**: Downloaded as `arraybuffer` and parsed client-side using `docx-preview` inside A4 aspect containers.
|
||||
* **Spreadsheets (`.xlsx`, `.xls`, `.csv`)**: Parsed client-side via SheetJS (`xlsx`) and rendered as HTML tables. Formatted with explicit dark slate text styles to remain readable regardless of the layout's light/dark mode theme.
|
||||
* **PowerPoint (`.pptx`, `.ppt`)**: Embedded via Microsoft Office Online Viewer in staging/production, falling back to dynamic mockup cards on localhost.
|
||||
|
||||
---
|
||||
|
||||
## 5. Security & Access Controls
|
||||
* **Content Security Policy (CSP)**: Customized in Express app helmet headers to permit iframe sandbox integrations from:
|
||||
```json
|
||||
"frame-ancestors": ["'self'", "http://localhost:5173", "http://localhost:5000"]
|
||||
```
|
||||
* **Legal Acceptance Gates**: Onboarding status `PENDING_ONBOARDING` restricts partner UI routing, requiring users to complete assigned legal agreement forms before viewing assets.
|
||||
35
memory.md
35
memory.md
@ -1,35 +0,0 @@
|
||||
# Developer Memory Log
|
||||
|
||||
This document records the exact state of the project, completed features, solved bugs, and historical changes to maintain continuity.
|
||||
|
||||
---
|
||||
|
||||
## 1. Core Completed Features
|
||||
|
||||
### A. Onboarding Legal Skip & MFA Control
|
||||
* **Onboarding Skip**: Implemented "None (No agreement required)" legal options. When a partner is invited or updated with no NDA/MSA requirement, the backend `AuthService` automatically bypasses signing steps and sets the user's status to `APPROVED`.
|
||||
* **MFA Toggle**: Added `mfaEnabled` options inside the partner invitation modal, partner editing forms, and backend API routes.
|
||||
|
||||
### B. Client-Side Document Previews
|
||||
* **Word Document Preview**: Integrated `docx-preview` to parse raw OpenXML array buffers and render them in-browser.
|
||||
* **Spreadsheet & CSV Preview**: Integrated SheetJS (`xlsx`) to parse spreadsheet buffers and generate clean HTML cell tables.
|
||||
* **Online Preview Button**: Enabled online preview buttons (Eye icon) for CSV files and text/code files by expanding the `isRenderable` utility in `AssetCard.tsx`.
|
||||
|
||||
### C. Responsive Full-Bleed Thumbnails
|
||||
* **Word & Spreadsheet Card Thumbnails**: Replaced static placeholders with dynamic rendered previews of the first page/sheet.
|
||||
* **Responsive Scaling**: Integrated a React `ResizeObserver` hook inside `DocxThumbnail.tsx` and `SpreadsheetThumbnail.tsx` to automatically calculate scaling factor based on card width, making cards fit their containers perfectly instead of sticking to the top-left corner.
|
||||
|
||||
### D. Clean Admin Deletion
|
||||
* **S3 Deletion Hook**: Updated backend `AssetService.deleteAsset` to detect files under `/uploads/` and dispatch a `DeleteObjectCommand` to the MinIO container bucket, cleaning up disk space on deletion.
|
||||
|
||||
---
|
||||
|
||||
## 2. Key Resolved Bugs
|
||||
|
||||
### A. CSV Text Preview Bypass
|
||||
* **Symptom**: CSV files were being treated as plain text files, rendering as comma-separated text blocks in a code viewport.
|
||||
* **Resolution**: Excluded `.csv` files and mime-types from the `isTextOrCodeAsset` filter inside `AssetViewerModal.tsx`. This routed them correctly to the SheetJS spreadsheet parser.
|
||||
|
||||
### B. Dark Mode Cell Invisible Text
|
||||
* **Symptom**: In dark mode, spreadsheet/CSV cells rendered as blank grids because text inherited the light mode/system white text color.
|
||||
* **Resolution**: Added explicit `.excel-thumbnail-container table { color: #0f172a }` and `.excel-preview-container table { color: #0f172a }` CSS rules to override dark mode layout text colors and keep tables fully readable.
|
||||
28
phases.md
28
phases.md
@ -1,28 +0,0 @@
|
||||
# Project Phases & Roadmap
|
||||
|
||||
This document structures past achievements and maps future development phases for the Tech4Biz Channel Partner Portal.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Secure Asset Library & Onboarding Gateway (COMPLETED)
|
||||
* **Secure Client-Side Previews**: Built browser-native preview engines for Word, PDF, Excel, and CSV files, bypassing external online view dependencies.
|
||||
* **Responsive Full-Bleed Thumbnails**: Integrated `ResizeObserver` to dynamically scale dynamic first-page/sheet previews to the size of the catalog grid cards.
|
||||
* **Onboarding Legal Skip**: Created a fallback route allowing administrators to skip legal NDAs/MSAs for trusted partners.
|
||||
* **MFA Security Gates**: Added MFA configuration toggles to both backend user registration and frontend administration panels.
|
||||
* **Disk/Storage Cleanup**: Integrated automatic MinIO file deletion routines into the administrative delete-asset workflow.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Multi-Company & Multi-Branch Organization Segregation (UPCOMING)
|
||||
* **Hierarchical Company Branches**: Extend `Organization` model to support sub-branches or multi-company profiles under a single parent entity.
|
||||
* **Rigorous Multi-Tenancy Scopes**: Refine database query interceptors in backend service layers to verify that users can only search, discover, or download assets explicitly tagged/shared to their current branch or organization hierarchy.
|
||||
* **Organization Admin Scopes**: Introduce organization-specific admins who can invite members and review download requests within their own company boundaries without global system privileges.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Client-Side Recommendations Engine (UPCOMING)
|
||||
* **Personalized Asset Suggestions**: Implement an asset recommendation widget on the partner dashboard recommending resources based on:
|
||||
* User's partner group classification.
|
||||
* Popularity (highest download counts).
|
||||
* Recently uploaded assets within matching folder categories.
|
||||
* **Activity-Based Feeds**: Display a "Recommended for You" section utilizing tag matching algorithms on the client catalog homepage.
|
||||
37
rules.md
37
rules.md
@ -1,37 +0,0 @@
|
||||
# Project Development Rules
|
||||
|
||||
This document outlines the strict guidelines and standards for pair-programming and code development across sessions.
|
||||
|
||||
---
|
||||
|
||||
## 1. Documentation Synchronization Rule (CRITICAL)
|
||||
Whenever any feature, file layout, database model, API endpoint, component, or system logic is created, modified, or deleted:
|
||||
* You **MUST** update the relevant sections of `architecture.md`, `memory.md`, and `phases.md` in the same developer turn/commit.
|
||||
* Documentation must match the codebase exactly; there must be **zero** discrepancy, assumptions, or trailing documentation debt.
|
||||
|
||||
---
|
||||
|
||||
## 2. Coding & Technical Standards
|
||||
|
||||
### A. Environment Variable Safety
|
||||
* Do **not** hardcode API endpoints, JWT secrets, S3 bucket names, or MinIO endpoints.
|
||||
* Always read configurations from `.env` (backend uses `process.env.VAR`, frontend uses `import.meta.env.VITE_VAR`).
|
||||
|
||||
### B. Security & Iframe Embedding Policies
|
||||
* Keep Express security configurations using `helmet` aligned.
|
||||
* **Frameguard must remain disabled** (`frameguard: false`) to allow authorized parent components to embed secure previews.
|
||||
* Content Security Policy (CSP) must contain `"frame-ancestors": ["'self'", "http://localhost:5173", "http://localhost:5000"]` to prevent browsers from blocking localized iframe previews.
|
||||
|
||||
### C. Client-Side Document Previews & Thumbnails
|
||||
* **Client-Side Processing**: Previews and thumbnails must run client-side. Use `docx-preview` for `.docx`, SheetJS (`xlsx`) for spreadsheets (`.xlsx`, `.xls`, `.csv`), and `PDF.js` for `.pdf`.
|
||||
* **Dark Mode Styling Safeguards**: Always force an explicit dark text color (`color: #0f172a`) inside bare spreadsheet HTML containers (such as `.excel-thumbnail-container` or `.excel-preview-container`) so that cell text is readable even if the application layout is in dark mode.
|
||||
* **Dynamic Full-Bleed Scaling**: Card thumbnails for Word and spreadsheet components must scale dynamically using a `ResizeObserver` based on the parent card width:
|
||||
```typescript
|
||||
scale = parentWidth / innerDocumentWidth
|
||||
```
|
||||
* **Legacy Format Fallbacks**: For formats where client-side rendering is impossible (such as legacy OLE binary `.doc` and `.ppt` formats), provide gorgeous, type-aware cover mockup views.
|
||||
|
||||
### D. File Cleanups upon Deletion
|
||||
* Always delete physical S3 objects when their database references are deleted:
|
||||
* In the backend asset controllers/services, verify if the asset URL starts with `/uploads/`.
|
||||
* If so, invoke `DeleteObjectCommand` on the S3 `s3Client` to remove the binary object from the MinIO bucket, preventing orphaned storage bloat.
|
||||
Loading…
Reference in New Issue
Block a user