Kaatiksen media arkisto tallentaa Discordiin lähetetyt kuvat, videot ja äänitiedostot. Selain näyttää median justified galleriana. Haku yhdistää SQLite FTS5 osumat ja Qdrantin semanttiset Gemini embedding osumat.
| Osa | Vastuu |
|---|---|
apps/web |
React ja TypeScript käyttöliittymä |
apps/api |
Fastify API, tiedostot, SQLite, esikatselut ja Qdrant |
apps/bot |
Discord tapahtumat ja /kaatis komento |
packages/contracts |
Jaetut API tyypit |
src/search |
Gemini ja Qdrant domain logiikka |
legacy/icons |
Vanhan Apache listauksen alkuperäiset tiedostotyyppi ikonit |
public |
Alkuperäiset mediatiedostot |
data/kaatis.sqlite |
Median metadata ja pysyvät työjonot |
data/thumbs |
Sisältöosoitteiset WebP ja WebM esikatselut |
data/qdrant |
Qdrantin pysyvä tallennus |
SQLite on metadatan lähde. Qdrant sisältää vain hakua varten tarvittavat vektorit ja payload tiedot. Mediaa ei kopioida Qdrantiin.
Compose käynnistää kuusi palvelua.
initvalmistelee kirjoitettavien hakemistojen omistajuudet.edgepalvelee selainbuildin, esikatselut ja alkuperäiset tiedostot Caddyllä.legacypalvelee old.kaatis.party Apache tyylisen tiedostolistauksen.apiomistaa kaikki kirjoitukset mediahakemistoon, SQLiteen ja Qdrantiin.botvälittää Discord tapahtumat sisäiselle APIlle.qdrantsuorittaa vektorihaun.
Caddyt avaavat vain localhost portit. Tuotannon Nginx välittää kaatis.party osoitteeseen 127.0.0.1:8089 ja old.kaatis.party osoitteeseen 127.0.0.1:8189.
Asenna riippuvuudet.
npm installKäynnistä käyttöliittymä.
npm run devKäynnistä API.
npm run api:startKäynnistä Discord botti.
npm run bot:startKopioi .env.example tiedostoksi .env ja täytä salaisuudet.
| Muuttuja | Tarkoitus |
|---|---|
DISCORD_BOT_TOKEN |
Discord botin tunniste |
MEME_CHANNEL_ID |
Kanava, jonka liitteet arkistoidaan |
DISCORD_GUILD_ID |
Slash komennon guild |
GEMINI_API_KEY |
Hakukyselyt ja embeddingit |
SEARCH_INTERNAL_TOKEN |
Botin ja APIn jaettu salaisuus |
PUBLIC_BASE_URL |
Julkinen osoite, oletus https://kaatis.party |
MEDIA_DB_PATH |
SQLite polku, oletus data/kaatis.sqlite |
UPLOAD_DIR |
Alkuperäisten tiedostojen polku, oletus public |
PREVIEW_ROOT |
Esikatselujen polku, oletus data/thumbs |
QDRANT_URL |
Qdrantin sisäinen osoite |
HTTP_PORT |
Caddyn localhost portti, oletus 8089 |
LEGACY_HTTP_PORT |
Legacy Caddyn localhost portti, oletus 8189 |
Sisäinen upload hyväksyy vain HTTPS osoitteita Discordin CDN hosteilta. Tiedoston enimmäiskoko on oletuksena 256 megatavua.
Kuvista luodaan WebP versiot leveyksillä 320, 640 ja 1280 pikseliä. GIF tiedostosta käytetään ensimmäistä kuvaa galleriassa.
Videosta luodaan samat WebP kuvat sekä lyhyt 480 pikseliä leveä mykistetty WebM. Selain lataa liikkuvan esikatselun vasta laatan lähestyessä ruutua.
Nykyinen arkisto lisätään työjonoon tällä komennolla.
docker compose run --rm api npm run media:backfillTyöjono on SQLitessä. Keskeytynyt ajo jatkuu seuraavalla API käynnistyksellä.
Esikatselujen backfill ei lähetä vanhoja medioita uudelleen Geminille. Videoiden semanttinen backfill käyttää erillistä Gemini Batch ajoa.
docker compose run --rm api npm run search:index:video-batch -- submit
docker compose run --rm api npm run search:index:video-batch -- status
docker compose run --rm api npm run search:index:video-batch -- importFTS5 hakee tarkat otsikko, tiedostonimi ja tekijäosumat. Gemini muuntaa kyselyn vektoriksi ja Qdrant hakee merkitykseltään sopivat kuvat sekä videoiden kuva ja ääniosumat.
Tulokset yhdistetään painotetulla reciprocal rank fusion menetelmällä. FTS5 paino on 1.25. Kuvien ja videoiden semanttisten listojen paino on 1.0. Jos Gemini tai Qdrant ei vastaa, API palauttaa FTS5 tulokset kentällä degraded: true.
Hakukyselyn embedding tallennetaan pysyvästi Qdrantiin. Sama kysely ei kuluta Geminiä uudelleen.
/kaatis muodostaa viimeisistä viesteistä lyhyen hakusanan Geminillä ja hakee sopivan median. /kaatis hakusana:<teksti> käyttää annettua hakua suoraan.
Uusi liite lähetetään APIlle Discord CDN osoitteena. API lataa tiedoston atomisesti, kirjoittaa metadatan ja jonottaa esikatselun sekä embeddingin. Discord viestin poisto poistaa alkuperäisen tiedoston, SQLite rivin, esikatselun ja Qdrant pisteet.
old.kaatis.party näyttää SQLiteen tallennetut kuvat, videot ja äänet vanhan Apache hakemistolistauksen muodossa. Taulukon Description sarake näyttää tekijän. Tiedostonimi, päivämäärä, koko ja kuvaus ovat lajiteltavissa Apache tyylisillä otsikkolinkeillä.
Legacy palvelu ei lue CSV tai .htaccess metadataa. Muut kuin nykyisen järjestelmän mediaformaatit palauttavat 404.
Rakenna ja käynnistä pino.
docker compose up -d --buildEnsimmäisessä käyttöönotossa tee SQLite varmuuskopio ennen skeemapäivitystä. Esikatselujen backfill voidaan ajaa vanhan palvelun ollessa käynnissä. Lopullinen vaihto tarvitsee lyhyen huoltokatkon, koska kirjoitusvastuu siirtyy botilta APIlle.
Jos vanhassa asennuksessa on keskeneräisiä Gemini Batch ajoja JSON tiedostossa SQLite tietokannan vieressä, siirrä ne SQLiteen ennen uuden APIn käynnistämistä.
docker compose run --rm api npm run media:migrate-batches