40 Commits
Author SHA1 Message Date
zk 7ea3c6cb08 fix: bun lock update (#1690) 2026-06-19 15:59:40 +01:00
zk a28fe51121 feat: this is cute i like it (#1688)
* feat: first draft of an import status viewer + callback

* feat: move off bun's redis client
2026-06-19 00:47:39 +01:00
zkandzk 8270d5360a fix: remove entropy (#1664)
Co-authored-by: zk <--global>
2026-06-14 13:51:24 +01:00
zk 0391fbacf0 feat: propogate lyko's fixes from lr2ir-dataset (#1644) 2026-06-06 15:34:37 +01:00
zk dcb7c8d41b feat: recaptcha->hcaptcha (#1577) 2026-05-24 16:09:23 +01:00
zk ae5e72aa89 fix: resize profile images on upload and cache redirect responses (#1564)
* fix: resize profile images on upload and add cache headers

Profile pictures were stored at original upload size (up to 1 MB) but
only ever displayed at 32–128 px, so every page load downloaded the full
original image. Additionally, no Cache-Control headers were set anywhere
in the pipeline, forcing a fresh round-trip through the API redirect and
CDN on every page view.

- Resize JPEG/PNG pfps to max 256×256 and banners to max 1920×1080 via
  sharp before storing; re-encode to WebP at 85% quality (GIFs skipped
  to preserve the animated-GIF easter egg)
- Hash the resized buffer so the CDN path reflects what's on disk
- Set ContentType and CacheControl: immutable on S3 PutObject so CDN
  edges and browsers cache the objects indefinitely (safe because paths
  are content-addressed via SHA-256)
- Add Cache-Control: public, max-age=3600, stale-while-revalidate=86400
  to the GET /pfp and GET /banner redirect responses so browsers cache
  the userId→CDN-URL mapping and skip the API hop on repeat visits

Fixes #1553

* chore: apply biome formatting

* chore: generate ImportTimestop kanel type

* feat: add backfill-media script to migrate existing profile images

One-off script that reads every user's existing pfp and banner from S3,
runs them through the same sharp resize/WebP pipeline as new uploads,
stores the result under the new content-addressed key with immutable
cache headers, and updates custom_pfp_location/custom_banner_location
in the DB.

Features:
- --dry-run flag to preview changes without writing anything
- Skips objects already at optimal size (idempotent)
- Gracefully handles missing S3 objects (logs + skips)
- Summary stats at the end
- Reads S3 config from CLI args or TACHI_CDN_SAVE_LOCATION_* env vars

* chore: apply biome formatting to backfill-media

* fix: resize animated GIFs to animated WebP via sharp animated:true

* test: rewrite change-pfp/banner tests as real S3 + sharp integration

Remove the CDN mock entirely. Tests now pass real image buffers through
sharp and verify the stored S3 object via CDNRetrieve:

- PNG/JPEG input → assert stored object is WebP, dimensions ≤256×256,
  smaller than the original
- GIF input → assert stored object is WebP
- Hash returned from the action == SHA256 of the stored WebP bytes
  (not the original upload)
- Delete tests upload a real pfp then delete it and verify CDNRetrieve
  throws afterwards

Also move change-pfp.test.ts from the isolated vitest project back to
the default pool now that it no longer uses vi.mock.

* chore: apply biome formatting to test file

* fix: use POSTGRES_TEST_HOST env var in bot vitest setup

Both vitest.globalSetup.ts and vitest.setup.ts hardcoded 'tachi-postgres'
(the dev server), but just bot-db-test-template-reset creates the template
on 'tachi-postgres-test' (the tmpfs test server). Workers then failed to
clone the template because they were looking on the wrong host.

Mirrors the pattern already used in the server package:
  process.env.POSTGRES_TEST_HOST ?? 'tachi-postgres-test'

* fix: update pfp router tests for WebP resize pipeline

The PUT tests were comparing the stored S3 bytes directly to the original
upload buffer. Since we now resize and re-encode to WebP, this always
fails. Also, following the mockApi redirect to fetch the bytes added a
slow supertest round-trip.

Replace with: read custom_pfp_location from the DB after PUT, fetch the
stored object directly via CDNRetrieve, and assert it is smaller than the
original (non-deterministic WebP compression makes exact byte comparison
inappropriate).

* fix: update banner router tests for WebP resize pipeline

* fix: tests

* fix: ci
2026-05-23 13:48:49 +01:00
zk f53d44b638 feat: homepage (#1563)
* feat: githooks, check before push

* feat: homepage
2026-05-23 10:07:48 +01:00
zk 180c86ed7d fix: bun lockfile 2026-05-22 16:39:31 +00:00
zk 00d76747e2 feat: kill tis (#1528) 2026-05-20 19:54:10 +01:00
zk c569243194 feat: remove mongo and all of its deps (#1525)
* feat: remove mongo and all of its deps

* feat: remove all mongodb logic+thin out some unused deps
2026-05-20 19:48:39 +01:00
zk 6d77ed3c48 feat: significantly better ci images (#1516) 2026-05-20 01:20:32 +01:00
zk a47e3ca1f6 feat(github-bot): use bliss logging and upsert PR comments (#1508)
Switch ghbot from console.* to structured bliss/pino logs and edit
existing bot comments on PR sync instead of posting a new one each push.
2026-05-19 23:06:22 +01:00
zk bef09c0a11 fix: ok, bun 2026-05-18 12:21:45 +00:00
zk eebe6aaddc fix: db optimisations, 2 2026-05-18 11:30:50 +00:00
zk ff06287e87 fix: this fucking regexp bug that has annoyed me for 4 years 2026-05-17 23:19:38 +00:00
zk b07e780953 fix: lockfile 2026-05-17 17:50:51 +00:00
zk acea12ec8a dasdatmeespresso 2026-05-16 19:53:23 +00:00
zk 2771244005 fix: dwa 2026-05-15 18:20:15 +01:00
zk d5c28aa61a unfuck sqlite 2026-05-03 15:04:24 +00:00
zk b8a98b581c if it hurts to breathe (open a window) (#58)
* if it hurts to breathe (open a window)

* clocked it.

* must sleep tonight, sorry

* feat: leaderboard now shows #1 if you're #1 even in ties
2026-04-22 22:26:43 +01:00
zk ea52824a4b seeds.tachi.ac 2026-04-21 23:25:54 +00:00
zk 2bc4c3a628 more (#53)
* checkpoint

* server compiles again

* fmt

* checkpoint

* last one out, get the lights

* euston station

* like, mostly good. I'm under the ocean right now.

* fix: some nonsense AI stuff

* fix: new eslint rules, and cleanup imports across the board

* feat: folder slug rewrite, email logic change, too

* fix: register must use txn not db

* checkpoint
2026-04-20 23:11:16 +01:00
zk edda03e916 sunday 5th apr (rip mark hollis) (#52)
* lots of work

* feat: move rg-stats in, ensure consistency in db queries

* the clocks dont work

* almost

* ok jesus been and gone now back to usual
2026-04-06 01:25:30 +01:00
zk dd2447c848 feat: i'm really worried about this bit, but empiricism will win (#41)
* feat: i'm really worried about this bit, but empiricism will win

* feat: light driving

* feat: migrate over user game status

* feat: custom scrollbar, and migrate over settings

* feat: eamusement csv movement

* fix: rm debug

* feat: shark reaction

* checkpoint

* feat: get tests passing again

* checkpoint

* feat: bms table sync

* feat: ugs snapshot and backsync bms pms

* feat: checkpoint

* feat: iidx playlists

* manic depression

* continues

* fly

* happy house

* we're happy here

* I think. 6 years is enough for me. This is killing me, and I am dying.
2026-03-31 23:37:51 +01:00
zk a0c03803e4 feat: kill conf.json5; env vars 4 life #envGang 2026-03-28 22:06:52 +00:00
zk 9d81f3565d god 2026-03-28 17:23:34 +00:00
zk 1bb32efd8a feat: search functionality 2026-03-28 13:15:03 +00:00
zk 7f5aa96779 way more actionizing 2026-03-20 02:07:30 +00:00
zk c80e2ea2ef feat: start actionising on the west coast 2026-03-19 20:20:11 +00:00
zk bfe5fad78f parity engine and endless iteration follows thee 2026-03-18 23:34:22 +00:00
zk c6ec8b9d6b feat: maybe. bliss. 2026-03-18 23:18:35 +00:00
zk 97fb305bdb feat: bot refactor to 'zenith' framework or whatever it will be called sort of 2026-03-18 21:55:34 +00:00
zk 6a9b002d1f onchurianism 2026-03-18 21:35:47 +00:00
zk 6c041e1f9a antimony 2026-03-18 20:20:03 +00:00
zk 63d87ee39d feat: move logger over 2026-03-13 17:57:48 +00:00
zk 4d489cbdea checkpoint 2026-03-13 17:35:10 +00:00
zk d7bb9541f6 refactor: migrate bot/ to a sensible logging solution 2026-03-12 20:19:27 +00:00
zk fc3e2bf8e1 refactor: config becomes zod&not shit 2026-03-12 19:59:38 +00:00
zk c2fcaca1ac fix: bun.lock 2026-03-12 18:27:56 +00:00
zk 5ea514cfa8 feat: first v3 refactor 2026-03-11 00:06:28 +00:00