@col/brand-assets
Versie: 1.0.0 Toegevoegd: 2026-08-03
Herkomst
Onderdeel van het assetbesluit in docs/specs/2026-08-03-v2-branding-en-auth-ontwerp.md:
bron in deze repo, kopie in de app, geen runtime-koppeling. Registry-items kunnen
geen binaire bestanden dragen (bestandsinhoud reist als tekst), dus dit item
levert in plaats daarvan het ophaalscript dat de binaire assets naar de
consumerende app kopieert.
De brondata komt uit supplier-onboarding-vercel/public/ (logo's en
achtergronden die daar al bestonden) en is overgezet naar assets/ in deze
repo — zie docs/specs/2026-08-03-v2-implementatieplan.md, Taak 1.
Waarvoor
Een Node-script (node scripts/pull-brand-assets.mjs) dat het manifest op
/assets/manifest.json ophaalt, ontbrekende of gewijzigde bestanden downloadt
naar public/brand/ in de consumerende app, en al up-to-date bestanden
overslaat op basis van bestandsgrootte.
Draai het eenmalig bij het opzetten van een app, en opnieuw wanneer een merkasset
in het design system wijzigt. Het is bewust geen build-stap — zo zie je in
git diff wanneer een logo verandert, en blijft de consumerende app werken als
het design system tijdelijk onbereikbaar is (de gekopieerde bestanden staan al
in de app zelf).
Gebruik het niet als je liever assets rechtstreeks vanaf
design-system.apps.coloriginz.com/assets/ laadt — dat is bewust niet de
architectuur (zie Bewuste keuzes).
De bestanden in public/brand/ zijn voor de browser, niet voor e-mailbijlagen:
Vercel serverless functions kunnen public/ op verzendmoment niet betrouwbaar
van de schijf lezen. Voor een e-maillogo embed je base64 in code — zie
docs/items/email-shell.md, "Wat je app moet leveren".
Wat je app moet leveren
Geen props of hooks — dit is een los script, geen React-component. Publieke "API" is de omgevingsvariabele en het gedrag:
| Omgevingsvariabele | Default | Betekenis |
|---|---|---|
BRAND_ASSETS_URL |
https://design-system.apps.coloriginz.com/assets |
Basis-URL waar het manifest en de bestanden vandaan komen. Override voor lokaal testen tegen npm run dev in deze repo. |
Gedrag:
- Haalt
<BRAND_ASSETS_URL>/manifest.jsonop. - Voor elk bestand in het manifest: als er al een lokaal bestand met exact
dezelfde grootte bestaat op
public/brand/<pad>, wordt het overgeslagen. Anders wordt het gedownload en weggeschreven (submappen worden aangemaakt). - Print een samenvatting (
N opgehaald, M ongewijzigd) en adviseertgit diffte controleren. - Bij een mislukte download (non-2xx) print het script een foutregel per
bestand en zet
process.exitCode = 1, maar gaat door met de overige bestanden — één kapotte asset blokkeert de rest niet.
Er is geen backend-contract in de zin van een API die de consumer zelf
implementeert; het contract is het manifestformaat dat deze repo serveert
({ generated, files: [{ path, bytes, sha256 }] }).
Bestanden
| Bestand | Landt in | Soort |
|---|---|---|
pull-brand-assets.mjs |
scripts/ |
glue — draait in de consumer, geen gedeelde runtime-afhankelijkheid terug naar dit design system |
Geen upstream shadcn-afhankelijkheden, geen cssVars.
Gebruikt door
| App | Sinds versie | Opmerkingen |
|---|---|---|
supplier-onboarding-vercel (Onboarding Portal) |
1.0.0 | Consumer #1, sinds 3 aug 2026. Script staat in scripts/pull-brand-assets.mjs, assets landen in public/brand/. |
floriday-app (Floriday middleware) |
1.0.0 | Consumer #2, sinds 3 aug 2026. Gebruikt alleen backgrounds/default.jpg en logos/coloriginz.png; de andere zes zijn meegekomen en staan ongebruikt in de repo. Zie de kanttekening hieronder over waar het script landt. |
Waar het script landt
De registry zet pull-brand-assets.mjs neer via de lib-alias, en die wijst in een
src/-project naar src/scripts/ — niet naar de scripts/ map waar het commentaar in het
bestand zelf naar verwijst. Consumer #2 heeft het handmatig verplaatst; het script gebruikt
process.cwd(), dus de locatie maakt voor de werking niets uit.
Gevolg: na een npx shadcn add @col/brand-assets --overwrite staat het er dubbel. Wie het
verplaatst, moet dat na elke update opnieuw doen.
Bewuste keuzes
- Bron hier, kopie in de app — geen runtime-laden vanaf
/assets. Rechtstreeks laden zou de architectuur ondermijnen die deze repo net probeert te bereiken: ligt deze deployment eruit, dan zou elke loginpagina, navbalk en formulierheader van een consumerende app daarvan afhangen, op productie. Het botst bovendien met de projectregel tegen externe URL's in e-mails (Ethereal en fragiliteit) — de onboarding-portal gebruikt daar allogo-base64.tsvoor. Eén bron voor hetzelfde logo is beter dan twee. - Vergelijking op bestandsgrootte (
bytes), niet op de meegeleverdesha256. Eenstat-achtige grootte-check is genoeg om "waarschijnlijk ongewijzigd" vast te stellen zonder het lokale bestand te moeten inlezen en hashen; desha256in het manifest is bedoeld voor consumers die zelf een strengere check willen, niet voor dit script. - Losse actie, geen build-stap. Bewust niet aangeroepen vanuit
next buildof eenpostinstall-hook: een asset-update moet zichtbaar zijn als een losstaande commit in de consumerende app, niet verstopt in een build-log. - Doorgaan na een mislukte download in plaats van meteen stoppen. Eén tijdelijk onbereikbaar bestand mag de rest van de synchronisatie niet blokkeren; de niet-nul exit-code aan het einde zorgt dat CI het toch opmerkt.
Bekende beperkingen
- De grootte-vergelijking beschermt niet tegen een bestand dat toevallig dezelfde bytegrootte heeft maar andere inhoud kreeg — in de praktijk verwaarloosbaar voor logo's/achtergronden, maar geen garantie.
- Geen retry-logica bij een mislukte download; opnieuw draaien is de manier om het te herstellen.
- Bij
shadcn add @col/brand-assetswordt het openingscommentaarblok van het script (uitleg + hetnode scripts/...-voorbeeld) door de CLI gestript — dat is bekend gedrag van de tool (zieverify-item.mjs) en geen bug van dit item. De code zelf komt ongewijzigd aan.