Arkkitehtuurin yleiskuva — Frontpics
Frontpics on TypeScript-monorepo, jossa on Next.js-verkkosovellus, NestJS-API, PostgreSQL/PostGIS-tietokanta, Redis/BullMQ-jono ja ajonaikaisesti valittava tiedostotallennus.
Ajonaikaiset osat
Selain
|
v
Next.js web (apps/web)
|
v
NestJS API (apps/api)
| |
v v
PostgreSQL/PostGIS Redis/BullMQ
|
v
StorageService
r2 | s3 | local
Tuotannossa sovellus ajetaan Docker Compose -pohjaisina blue/green-pinoina Nginxin takana. PostgreSQL ja Redis ovat jaettuja infrastruktuuripalveluja.
Verkkosovellus
apps/web sisältää:
- julkisen etusivun ja kuvamarkkinapaikan;
- ostajan krediitit, laskutuksen, kuvaustilaukset ja lataukset;
- kuvaajan latauksen, keikat, kuvat, ansiot, tilitykset ja profiilin;
- moderaattorin työkalut;
- palkanlaskennan raportit;
- ylläpidon.
Reittisuojaus ja lokalisointi kuuluvat tiedostoon apps/web/src/proxy.ts.
API
apps/api on NestJS 11 -sovellus Fastify-adapterilla.
Keskeiset moduulit:
- auth ja users;
- images ja upload;
- orders, wallets, payouts ja invoices;
- shooting requests;
- admin;
- feedback ja incoming emails;
- storage;
- queue/image processing;
Kaikki reitit ovat polun /api/v1 alla.
JWT-validointi palauttaa { id, email, role }. Palveluissa käytetään user.id.
Tietokanta
Prisma-skeema on tietokannan lähde. Tärkeitä malleja ovat:
UserPhotographerProfileAgentProfileImageImageFileLocationTagOrder/OrderItemCreditWallet/CreditTransactionPayoutShootingRequestAgencyBrand
Enum-arvot ovat pienellä kirjoitettua snake_case-muotoa, esimerkiksi pending_review.
Tallennus
Tiedostotallennus kulkee StorageService-kerroksen kautta. Aktiivinen backend määritetään Redisissä:
config:storage_backend = r2 | s3 | local
Olemassa olevat tiedostot pysyvät siinä backendissä, jossa ne luotiin. Muutos vaikuttaa uusiin tiedostoihin.
Kuvan lataus
Kuvaaja valitsee tiedostot
-> web lukee EXIF/hash-tiedot ja ratkaisee osoitteen/GPS:n
-> POST /upload/presigned
-> selain lataa tiedostot suoraan tallennukseen
-> POST /upload/check-duplicates
-> POST /upload/confirm metatiedoilla
-> API luo Image/Location/Tag-tietueet
-> API jonottaa BullMQ-käsittelyn
-> worker luo variantit ja ImageFile-tietueet
-> kuva siirtyy pending_review-tilaan
-> ylläpito hyväksyy kuvan aktiiviseksi
Osto
Ostaja valitsee yhden tai useamman kuvan
-> valinnainen laskutusviite
-> POST /orders
-> API tarkistaa saldon ja duplikaattiostot
-> transaktio luo Order/OrderItem-tietueet
-> ostajan lompakkoa veloitetaan
-> kuvaajan lompakkoa hyvitetään
-> lataukset avautuvat
Ostaminen toimii työpöydällä ja mobiilissa kuvan esikatselumodaalissa sekä ruudukon valintapalkissa.
Lataus ja brändäys
Ostaja avaa ostetun kuvan
-> GET /images/:id/download/:orderItemId
-> API palauttaa allekirjoitetun latausosoitteen ja toimistobrändin
-> web lisää tarvittaessa vesileiman ja kohdepinssin
-> lopullinen kuva latautuu selaimessa
Brändäys ratkaistaan keskitetysti AgencyBrand-mallista.
Kuvaustilaukset
Ostaja luo kuvaustilauksen
-> osoitehaku tai API-geokoodaus tallentaa koordinaatit
-> ostajalta ei varata tai vähennetä krediittejä
-> kuvaajat näkevät avoimet keikat listalla ja kartalla
-> kuvaaja ottaa keikan
-> kuvaaja merkitsee keikan valmiiksi
-> kuvaajan lompakkoa hyvitetään
Kuvaustilauksen valmistuminen ei luo tilitystä automaattisesti.
Tilitykset
Kuvaaja pyytää tilitystä
-> API tarkistaa pankkitiedot ja vähimmäissaldon
-> Payout(status=pending) luodaan
-> krediitit varataan/vähennetään
-> valinnainen kuvaajan viite tallennetaan linkitettyyn tapahtumaan
-> ylläpito näkee odottavan tilityksen ja viitteen
-> ylläpito merkitsee maksetuksi tai hylkää ja palauttaa krediitit
Operatiiviset jonot
Ylläpidon numeromerkit tulevat endpointista GET /admin/action-counts:
- odottavat kuvat;
- lukemattomat sähköpostit;
- avoimet palautteet;
- odottavat tilitykset.