Spaces:
Sleeping
Sleeping
| title: MplusKassa Studio | |
| emoji: 🧾 | |
| colorFrom: blue | |
| colorTo: green | |
| sdk: docker | |
| app_port: 7860 | |
| pinned: false | |
| license: apache-2.0 | |
| # MplusKassa Studio | |
| MplusKassa Studio is een MVP voor ondernemers die snel betere productbeelden nodig hebben voor hun kassa, bestelzuil, webshop of menuscherm. | |
| De gebruiker uploadt bestaande productfoto's, kiest het type beeld en laat de Studio een verkoopklare variant maken. Geen losse AI-tools, geen technische instellingen, maar een begeleide flow van foto naar bruikbaar resultaat. | |
| ## Demo | |
| Drie losse productfoto's worden samengebracht tot een menu-deal compositie op een schone witte achtergrond. | |
| | Hoofdproduct | Drank | Bijgerecht | | |
| | --- | --- | --- | | |
| |  |  |  | | |
| **Gegenereerd resultaat** | |
|  | |
| Deze demo-output komt uit een echte end-to-end run via de backend en Kaggle GPU. De README gebruikt een vaste kopie in `docs/`, zodat nieuwe testruns het voorbeeld niet overschrijven. | |
| ## Waarom Dit Bestaat | |
| Veel ondernemers hebben wel productfoto's, maar die zijn niet altijd direct geschikt voor verkoop: | |
| - de achtergrond is rommelig; | |
| - producten hebben verschillende lichtval of kwaliteit; | |
| - losse beelden voelen niet als één aanbieding; | |
| - iemand moet handmatig knippen, schalen en combineren; | |
| - menu- en webshopbeelden moeten consistent zijn. | |
| Studio maakt daar een eenvoudige workflow van: | |
| ```text | |
| productfoto's uploaden -> type beeld kiezen -> beeld maken -> resultaat controleren | |
| ``` | |
| De app is bedoeld als assistent voor één concrete taak: betere productafbeeldingen maken. | |
| ## Wat De MVP Kan | |
| - Losse productfoto's uploaden. | |
| - Een map met meerdere beelden uploaden. | |
| - Kiezen tussen `Los product` en `Menu deal`. | |
| - Een klantvriendelijke prompt invullen, bijvoorbeeld: `Maak een professionele fastfood menu deal op een schone witte menu-achtergrond`. | |
| - Echte beelden genereren via een server-side FLUX.2 model op Kaggle GPU. | |
| - Origineel en resultaat naast elkaar controleren. | |
| - Een e2e-bewijsrapport genereren met inputbeelden, outputbeeld en timing. | |
| ## Belangrijk Voor De Output | |
| De huidige menu-deal prompt stuurt op drie dingen: | |
| - exacte samenstelling: geen extra producten, dubbele drankjes of extra sauzen; | |
| - herkenbare producten: vorm, materiaal, glas, ijs, kleur en textuur moeten dicht bij de input blijven; | |
| - commerciële compositie: hoofdproduct links, drank centraal/achter, bijgerecht rechts, met witte achtergrond en realistische schaduw. | |
| Tekst, prijzen en actielabels worden bewust niet door het image model gemaakt. Die horen later als aparte grafische laag bovenop het beeld. | |
| ## Laatste E2E Resultaat | |
| Laatste echte Kaggle-run: | |
| ```text | |
| Model inference only: 77.71s | |
| Model load: 54.50s | |
| Setup before model load: 31.13s | |
| Total Kaggle kernel runtime: 163.40s | |
| GPU: Tesla T4 | |
| ``` | |
| Na een nieuwe e2e-run staan de actuele testbestanden hier: | |
| ```text | |
| test-results/e2e/kaggle-demo/result.md | |
| test-results/e2e/kaggle-demo/generated.png | |
| test-results/e2e/kaggle-demo/generated-<run>.png | |
| ``` | |
| ## Architectuur | |
| De app bestaat uit: | |
| - Angular 21 frontend voor de begeleide productflow; | |
| - Node/Express backend voor uploads, validatie en provider-aansturing; | |
| - async generation jobs: `POST /api/generations` maakt een taak aan, `GET /api/generations/:jobId` levert status en resultaat; | |
| - Kaggle als remote GPU-runner voor echte generatie; | |
| - Docker-voorbereiding voor app, Postgres en MinIO/S3; | |
| - e2e-rapportage via Playwright. | |
| Kaggle credentials blijven server-side. De frontend ziet alleen de app-flow en krijgt geen toegang tot secrets of providerinstellingen. | |
| ## Lokaal Starten | |
| Maak eerst `.env` op basis van `.env.example` en vul je Kaggle configuratie in. | |
| ```powershell | |
| npm install | |
| npm run backend:dev | |
| npm run start -- --host 127.0.0.1 --port 5000 | |
| ``` | |
| Open daarna: | |
| ```text | |
| http://127.0.0.1:5000 | |
| ``` | |
| ## Kaggle Configuratie | |
| Voor lokale ontwikkeling wordt de Kaggle CLI via `uv` gebruikt. | |
| ```env | |
| GENERATION_PROVIDER=kaggle | |
| COMMERCIAL_MODE=1 | |
| FLUX_MODEL_ID=black-forest-labs/FLUX.2-klein-4B | |
| KAGGLE_COMMAND=uv run --with kaggle kaggle | |
| KAGGLE_USERNAME=jouw-kaggle-username | |
| KAGGLE_ACCELERATOR=NvidiaTeslaT4 | |
| KAGGLE_USE_SMALL_DECODER=0 | |
| KAGGLE_INFERENCE_STEPS=4 | |
| KAGGLE_CACHE_KERNEL_REF=jolvangeest/mplus-flux2-cache | |
| KAGGLE_POLL_INTERVAL_MS=5000 | |
| KAGGLE_POLL_TIMEOUT_MS=7200000 | |
| ``` | |
| `FLUX_MODEL_ID` kiest de server-side modelroute. De MVP gebruikt nu de commercial-safe Kaggle-route voor FLUX.2 `[klein] 4B`. Laat `COMMERCIAL_MODE=1` aan in productie, zodat non-commercial modelroutes niet per ongeluk geselecteerd kunnen worden. | |
| Kaggle OAuth login: | |
| ```powershell | |
| uv run --with kaggle kaggle auth login --force | |
| ``` | |
| Cache-kernel opnieuw pushen: | |
| ```powershell | |
| npm run kaggle:cache:push | |
| ``` | |
| ## Testen | |
| Snelle checks: | |
| ```powershell | |
| npm run test:integration | |
| npm run test:backend | |
| npm run build:all | |
| ``` | |
| Echte Kaggle e2e: | |
| ```powershell | |
| $env:E2E_PORT="5010" | |
| npx playwright test e2e/studio-flow.spec.ts --project=chromium --workers=1 | |
| ``` | |
| De echte e2e duurt meestal meerdere minuten door Kaggle scheduling, dependency setup en model load. | |
| ## Docker En Publiceren | |
| Voor een private testversie: | |
| 1. Gebruik de private GitHub repo. | |
| 2. Deploy met Docker op een host die server-side secrets ondersteunt. | |
| 3. Zet Kaggle credentials als secrets op de host. | |
| 4. Deel alleen de app-URL met collega's. | |
| Zie `DEPLOYMENT.md` voor de Docker-route en `docs/multi-user-architecture.md` voor de multi-user richting met Postgres, MinIO/S3 en per-user Kaggle isolation. | |
| ## Gratis Demo Host | |
| Voor een gratis private demo is een Docker-based Hugging Face Space geschikt. Gebruik daar `PORT=7860` en zet secrets server-side: | |
| - `GENERATION_PROVIDER=kaggle` | |
| - `COMMERCIAL_MODE=1` | |
| - `FLUX_MODEL_ID=black-forest-labs/FLUX.2-klein-4B` | |
| - `KAGGLE_COMMAND=kaggle` | |
| - `KAGGLE_USERNAME=<kaggle-user>` | |
| - `KAGGLE_API_TOKEN=<kaggle-token>` | |
| Deze route is bedoeld als demo-host. Jobs zijn nog in-memory en resultaten blijven niet persistent na restart/sleep. | |
| Deploy via CLI: | |
| ```powershell | |
| npm run deploy:check | |
| $env:HF_TOKEN="hf_..." | |
| $env:HF_SPACE_ID="jouw-hf-naam/mplus-studio" | |
| $env:KAGGLE_USERNAME="jouw-kaggle-username" | |
| $env:KAGGLE_API_TOKEN="jouw-kaggle-token" | |
| npm run deploy:huggingface | |
| ``` | |
| De deploy-script maakt een private Docker Space aan, zet de Space secrets en uploadt de repo zonder lokale `.env`, `node_modules`, `dist`, testresultaten of graphify-output. | |
| ## Roadmap | |
| De volgende stap is niet meer knoppen toevoegen, maar de workflow slimmer en betrouwbaarder maken: | |
| - presets per branche, zoals snackbar, lunchroom, retail of bakkerij; | |
| - review-stap met goedkeuren, afkeuren en opnieuw proberen; | |
| - meerdere outputvarianten per run; | |
| - automatische tekst en prijzen als aparte grafische laag; | |
| - database en object storage voor multi-user gebruik; | |
| - persistente job queue voor multi-instance hosting; | |
| - providerlaag uitbreiden richting betaalde BFL API-modellen waar dat commercieel zinvol is. | |