|
| 1 | +# ScrapFlow SA – Enterprise Scrapyard Management System |
| 2 | + |
| 3 | +[](https://dotnet.microsoft.com/en-us/apps/aspnet) |
| 4 | +[](https://react.dev/) |
| 5 | +[](https://www.postgresql.org/) |
| 6 | +[](https://tailwindcss.com/) |
| 7 | +[](https://www.docker.com/) |
| 8 | + |
| 9 | +**ScrapFlow SA** is a full-stack, production-ready solution built specifically for the South African scrap metal industry. It modernizes the legacy "pen-and-paper" metal trade with a high-performance, **SAPS/ITAC-compliant** digital platform. |
| 10 | + |
| 11 | +--- |
| 12 | + |
| 13 | +## 📽️ The Problem vs. The Solution |
| 14 | + |
| 15 | +### The Problem |
| 16 | + |
| 17 | +Legacy scrapyards in South Africa face three existential threats: |
| 18 | + |
| 19 | +1. **Compliance Chaos**: The _South African Second-Hand Goods Act_ and the recent **2024/2025 Metal Cash Ban** require strict record-keeping. Yards using paper registers often fail SAPS audits, leading to heavy fines or license revocation. |
| 20 | +2. **Operational Blindness**: Without real-time inventory tracking, owners are unaware of their exact tonnage on hand or their true profit margins after price fluctuations. |
| 21 | +3. **The Electronic Payment Gap**: Switching from cash to electronic payments (EFT) is a huge administrative burden without an integrated workflow to track proof-of-payments. |
| 22 | + |
| 23 | +### The ScrapFlow Solution |
| 24 | + |
| 25 | +ScrapFlow digitizes the entire lifecycle of a scrapyard transaction, ensuring that **compliance is baked into the code, not an afterthought.** By hard-blocking non-compliant actions (like missing ID photos or lacking EFT references), it acts as a "Digital Auditor" for the yard. |
| 26 | + |
| 27 | +--- |
| 28 | + |
| 29 | +## 🌟 Key Features |
| 30 | + |
| 31 | +### ⚖️ 1. Compliance-First Engine |
| 32 | + |
| 33 | +- **Automatic Cash-Ban Enforcement**: The `TicketService` strictly prevents completion without valid EFT references. |
| 34 | +- **Mandatory ID/Photo Capture**: Integrated Media API captures 3 mandatory photos (Seller, Load, ID) before a ticket can be finalized. |
| 35 | +- **Audit-Ready Registers**: Rolling registers stored for 5 years as required by the Second-Hand Goods Act. |
| 36 | + |
| 37 | +### 🍎 2. Premium Apple-Style UX |
| 38 | + |
| 39 | +- **Aesthetic Engineering**: A minimalist, high-contrast UI designed for the harsh lighting conditions of a scrapyard. Built with glassmorphism and Tailwind's emerald palette. |
| 40 | +- **Weighbridge Integration**: Direct communication with industrial scales via the **Web Serial API**. |
| 41 | + |
| 42 | +--- |
| 43 | + |
| 44 | +## 🛠️ Engineering Challenges & Solves |
| 45 | + |
| 46 | +Building a system for a highly regulated environment revealed several technical hurdles: |
| 47 | + |
| 48 | +### 🔄 1. The Circular Dependency Trap |
| 49 | + |
| 50 | +**Problem**: During the split between `Application` and `Infrastructure` layers, I encountered a circular dependency where services needed the `DbContext`, but the `DbContext` needed service-related logic. |
| 51 | +**Solution**: I moved high-level business services (like `TicketService`) into the **Infrastructure layer**. By implementing interfaces defined in the `Application` layer, I maintained Clean Architecture principles while resolving the cyclic reference. |
| 52 | + |
| 53 | +### 💉 2. Dependency Injection & Service Scoping |
| 54 | + |
| 55 | +**Problem**: Standalone services (like the `NotificationService` for WhatsApp) initially threw runtime errors due to missing `ILogger` implementations and improper DI registrations. |
| 56 | +**Solution**: I standardized DI registrations in `Program.cs` and utilized generic `ILogger<T>` patterns. In unit tests, I used **Moq** to provide verified mock loggers, ensuring the business logic could be tested in isolation from external logging providers. |
| 57 | + |
| 58 | +### 🧪 3. In-Memory Database Versioning |
| 59 | + |
| 60 | +**Problem**: When setting up the xUnit test suite, the latest `InMemoryDatabase` version (v10) was incompatible with the project's .NET 8 target. |
| 61 | +**Solution**: I performed a manual downgrade to **Microsoft.EntityFrameworkCore.InMemory v8.0.0**, aligning the test infrastructure with the core runtime and ensuring stable "database-in-memory" testing for compliance rules. |
| 62 | + |
| 63 | +--- |
| 64 | + |
| 65 | +## 🧠 What I Learnt |
| 66 | + |
| 67 | +1. **Industry-Specific Architecture**: Learnt how to translate legal requirements (SAPS/ITAC) into strict software "guards" and validation logic. |
| 68 | +2. **Browser-Hardware Interfacing**: Explored the power of the **Web Serial API** to bridge the gap between industrial hardware (scales) and modern web browsers. |
| 69 | +3. **Offline-First Resilience**: Implemented PWA strategies (Service Workers + IndexedDB) to ensure data integrity even when South African yard connectivity is unstable. |
| 70 | +4. **Clean Architecture Discipline**: Deepened my understanding of how to maintain strict separation of concerns even when complex infrastructure dependencies arise. |
| 71 | + |
| 72 | +--- |
| 73 | + |
| 74 | +## 🏗️ Technical Architecture |
| 75 | + |
| 76 | +```mermaid |
| 77 | +graph TD |
| 78 | + API[ScrapFlow.API] --> APP[ScrapFlow.Application] |
| 79 | + INFRA[ScrapFlow.Infrastructure] --> APP |
| 80 | + INFRA --> DOMAIN[ScrapFlow.Domain] |
| 81 | + APP --> DOMAIN |
| 82 | +
|
| 83 | + subgraph "Infrastructure" |
| 84 | + DB[(PostgreSQL)] |
| 85 | + SignalR[SignalR Hubs] |
| 86 | + Comp[Compliance Engine] |
| 87 | + Notif[Notification Service] |
| 88 | + end |
| 89 | +``` |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## 🚀 Getting Started |
| 94 | + |
| 95 | +1. **Docker Quick Start**: `docker-compose up --build` |
| 96 | +2. **Backend**: `cd src/ScrapFlow.API && dotnet run` |
| 97 | +3. **Frontend**: `cd scrapflow-client && npm run dev` |
| 98 | +4. **Tests**: `dotnet test` |
| 99 | + |
| 100 | +--- |
| 101 | + |
| 102 | +_Designed & Engineered for South African Scrapyards._ |
0 commit comments