160 Commits
Author SHA1 Message Date
github-actions[bot] 8b29a50e18 chore(backend): release 1.0.2
# [thingport-backend-v1.0.2](https://github.com/TautvydasDerzinskas/Thingport/compare/thingport-backend-v1.0.1...thingport-backend-v1.0.2) (2026-10-18)

### Bug Fixes

* download from Thingiverse with a Chrome TLS fingerprint ([8e6e5b2](https://github.com/TautvydasDerzinskas/Thingport/commit/8e6e5b2e0ee63b8d3c09bbbd3a086ad5543d2974))
* ensure Thingiverse gets browser agent ([40d36a4](https://github.com/TautvydasDerzinskas/Thingport/commit/40d36a4b20fc70133721f0ff60edf1240fa69030))
2026-10-18 02:50:13 +00:00
Tautvydas Derzinskas 8e6e5b2e0e fix: download from Thingiverse with a Chrome TLS fingerprint
Thingiverse's Cloudflare now challenges every request whose TLS handshake
isn't a browser's, whatever the headers or cookies, so file downloads,
preview images and API calls all failed. Route all thingiverse.com
requests through impit, which impersonates Chrome.
2026-10-18 04:38:47 +02:00
Tautvydas Derzinskas 40d36a4b20 fix: ensure Thingiverse gets browser agent 2026-10-17 23:22:32 +02:00
Tautvydas Derzinskas 7432b2125b Merge pull request #59 from TautvydasDerzinskas/refactor/update-docs-outdated-comments
docs: update docs and outdated comments
2026-10-17 22:31:25 +02:00
Tautvydas Derzinskas 2a1972b4f0 docs: update docs and outdated comments 2026-10-17 22:25:42 +02:00
Tautvydas Derzinskas 01e817498b Merge pull request #58 from TautvydasDerzinskas/ci/improve-ci-processes
ci: improve ci processes
2026-10-17 22:01:30 +02:00
Tautvydas Derzinskas 66938d8ecf ci: add manual version parameter for docker builds and fix release retry logic 2026-10-17 21:51:08 +02:00
github-actions[bot] 8a39a87b6c chore(backend): release 1.0.1
# [thingport-backend-v1.0.1](https://github.com/TautvydasDerzinskas/Thingport/compare/thingport-backend-v1.0.0...thingport-backend-v1.0.1) (2026-10-17)

### Bug Fixes

* rename Thingiverse Access Token to App Token to match what it provides ([cc41076](https://github.com/TautvydasDerzinskas/Thingport/commit/cc4107694aa0f35a234099a1fabaa840663cd29e))
* retry file downloads blocked by Cloudflare or rate limits ([b7c2f36](https://github.com/TautvydasDerzinskas/Thingport/commit/b7c2f36aced158b74072cb1f3507f4d83c58edf5))
2026-10-17 19:29:59 +00:00
Tautvydas Derzinskas b7c2f36ace fix: retry file downloads blocked by Cloudflare or rate limits
Retry downloads once with a delay when blocked by a 429 or Cloudflare
challenge, then report the failure so the caller can handle it. Limit
Thingiverse download concurrency to 2 to reduce triggering rate limits.
2026-10-17 20:48:38 +02:00
Tautvydas Derzinskas cc4107694a fix: rename Thingiverse Access Token to App Token to match what it provides 2026-10-17 20:27:58 +02:00
github-actions[bot] a89adff9cf chore(backend): release 1.0.0
# thingport-backend-v1.0.0 (2026-10-17)

### Bug Fixes

* 3mf model preview default to proper solid ([46b8687](https://github.com/TautvydasDerzinskas/Thingport/commit/46b8687d1d25c7b62307340b28108fe8966fa269))
* adjust downloads page ([58c773b](https://github.com/TautvydasDerzinskas/Thingport/commit/58c773b955131af5a4ae8e9c3d9ccc4255f23d8b))
* **ai:** disable categorization when last model is deleted ([bfc3fa0](https://github.com/TautvydasDerzinskas/Thingport/commit/bfc3fa0d72f86eeb508031a2457c9574a4421eca))
* **ai:** explain answers cut off by the token limit, and log AI and import runs ([#16](https://github.com/TautvydasDerzinskas/Thingport/issues/16)) ([7488793](https://github.com/TautvydasDerzinskas/Thingport/commit/748879311acebf47929bac613cce85ba4f0dc265))
* **ai:** show why a recategorization failed ([5fcadfb](https://github.com/TautvydasDerzinskas/Thingport/commit/5fcadfb179eeb8f40bb597a2826fa65f605ee256))
* allow replacing a model's only file in the edit dialog ([fc3f3ef](https://github.com/TautvydasDerzinskas/Thingport/commit/fc3f3efd48b9e926549773610e9d218780a28f21))
* big collection import printables ([8cb97bd](https://github.com/TautvydasDerzinskas/Thingport/commit/8cb97bd315a7a4a53c1879432679cdeb6f42bf71))
* correct multi-part 3MF previews and stop risky in-browser fallback ([65236c5](https://github.com/TautvydasDerzinskas/Thingport/commit/65236c5803b0624eced5fea069cd9594abeeeade))
* count queued links as models and let imported images replace 3D renders ([dd4d259](https://github.com/TautvydasDerzinskas/Thingport/commit/dd4d2592eae358357f71be13ac305d7219381d30))
* couple ux improvements ([030b155](https://github.com/TautvydasDerzinskas/Thingport/commit/030b1553e170b75c46766ee285dad21f0608e957))
* decode UTF-8 filenames delivered in the Latin-1 Content-Disposition header ([#3](https://github.com/TautvydasDerzinskas/Thingport/issues/3)) ([b732992](https://github.com/TautvydasDerzinskas/Thingport/commit/b73299222a3c086d6663bc2c59a7b7f0902ac755))
* derive the 3D preview memory budget from available memory ([5685514](https://github.com/TautvydasDerzinskas/Thingport/commit/5685514da632c4aa407d8e79d5f0ffddac479815))
* distinguish Thingiverse rate limits from auth errors and add AI run logging ([c5e5ab4](https://github.com/TautvydasDerzinskas/Thingport/commit/c5e5ab460e336e2b4eb071f8928d77b96cc36ea4))
* **extension:** check a MakerWorld collection against the library in one call ([44c687b](https://github.com/TautvydasDerzinskas/Thingport/commit/44c687b3ae7ba96a7246ece73d79212733cfd449))
* file upload file name utf8 issues ([6d34243](https://github.com/TautvydasDerzinskas/Thingport/commit/6d34243b89fe5f4e08f1fe9cc1fcb784d55d447d))
* import issues ([0d1efdb](https://github.com/TautvydasDerzinskas/Thingport/commit/0d1efdba02149f00ac3d0aca279cbe35e7b1e97e))
* importing models due preview generation uses all resources ([355833c](https://github.com/TautvydasDerzinskas/Thingport/commit/355833ca240865bf89684c4cb4bf05eb4648ddc6))
* **import:** limit manual CAPTCHA cooloff lifts to one per 5 minutes, require value on captcha keys ([bf083bc](https://github.com/TautvydasDerzinskas/Thingport/commit/bf083bcb26d2d49cafdc270523a210a15ad918da))
* **import:** stop flagging models that mention robots as a MakerWorld CAPTCHA, and let a manual retry try again ([#18](https://github.com/TautvydasDerzinskas/Thingport/issues/18)) ([d70dcfe](https://github.com/TautvydasDerzinskas/Thingport/commit/d70dcfeac2c788686728598c6d3c61b9f4cce369))
* improve bookmarks ui ([01f8812](https://github.com/TautvydasDerzinskas/Thingport/commit/01f8812cef9abf45824038d735eed6d9b2d9f731))
* include MakerWorld gallery images when importing from the model page ([e87eb39](https://github.com/TautvydasDerzinskas/Thingport/commit/e87eb39ab6aa0cb8f8ea465c0407f0ae8c71b6e0))
* make link-authors test deterministic ([9ada95b](https://github.com/TautvydasDerzinskas/Thingport/commit/9ada95b0a23fc949de3a57f413f423edddfd587a))
* make storage template collection and creator tokens reflect real data ([32710f2](https://github.com/TautvydasDerzinskas/Thingport/commit/32710f25e7b1011b9dc85bbbb67d403f6381a14a))
* make sure authors are removed when no models assigned to them ([55f5aaa](https://github.com/TautvydasDerzinskas/Thingport/commit/55f5aaa4a0473e23f87933f2347e7ef1bd75bb45))
* maker world importing ([476895f](https://github.com/TautvydasDerzinskas/Thingport/commit/476895f72f2d5327b1b193d8bfb7eddb4bb3c38e))
* MakerWorld author to print linking ([60eb0b9](https://github.com/TautvydasDerzinskas/Thingport/commit/60eb0b90feb2fefb1296a07a792ca0965a1e39ba))
* Makerworld import issues + allowing import different profiles ([303ab91](https://github.com/TautvydasDerzinskas/Thingport/commit/303ab918ea9b1f2d6866baf89f11b601364a1a36))
* minor adjustments in regards of import redirects and authors ([f187b9f](https://github.com/TautvydasDerzinskas/Thingport/commit/f187b9f25ec2cadf12ca03430c601ec0077b27bc))
* minor fixes along admin ([75de79c](https://github.com/TautvydasDerzinskas/Thingport/commit/75de79c4bcf6cc30bd79739bc8ff729718088244))
* minor fixes in UI ([f93bfc7](https://github.com/TautvydasDerzinskas/Thingport/commit/f93bfc7db4de24d07d03d30cfa51d988a87f76da))
* more than 11 models printables import ([27948c0](https://github.com/TautvydasDerzinskas/Thingport/commit/27948c01eef2202d851098f82972194c67f47d63))
* move preview generation to own separate thread ([ba08d30](https://github.com/TautvydasDerzinskas/Thingport/commit/ba08d30e1ee5685c67260886d4edb87e82332e1d))
* profile menu chips ([f903abc](https://github.com/TautvydasDerzinskas/Thingport/commit/f903abcd293b77adce74f0d786b6fa462ff4ef3b))
* show a proper error message when MakerWorld cookie fails due flareSolverr ([a81765e](https://github.com/TautvydasDerzinskas/Thingport/commit/a81765e1caff377ef442d3202ecebb6b566ebf92))
* skip a stale MakerWorld defaultInstanceId when picking the print profile ([#15](https://github.com/TautvydasDerzinskas/Thingport/issues/15)) ([d5ae809](https://github.com/TautvydasDerzinskas/Thingport/commit/d5ae80951cf69a9a4db118eee4f68d332f0af17a)), closes [#14](https://github.com/TautvydasDerzinskas/Thingport/issues/14)
* update Makerworld import logic ([3bc4f9c](https://github.com/TautvydasDerzinskas/Thingport/commit/3bc4f9c96dfe0b07de83d3fbff113efb3d14a2a1))
* various small UI issues ([8ba368e](https://github.com/TautvydasDerzinskas/Thingport/commit/8ba368e209c7d56e4ee48e5bf042e777f19d5b0a))

### Features

* ability to link multiple AIs ([56f173a](https://github.com/TautvydasDerzinskas/Thingport/commit/56f173a20b574014f5a29c6c8bbcc38f71c3dda8))
* accept MakerWorld page data sent with an extension import ([616a8b8](https://github.com/TautvydasDerzinskas/Thingport/commit/616a8b82c3657727b80da1fa924f35a32ca46d38))
* add ability to enable catpcha ([6a6a87e](https://github.com/TautvydasDerzinskas/Thingport/commit/6a6a87e38d8a8b65edf137171dfb6ff15dde3976))
* add admin job to refetch all user descriptions ([0cc27c9](https://github.com/TautvydasDerzinskas/Thingport/commit/0cc27c9eb618154c477dac5bd9cb1361eb7d291c))
* add Anycubic Slicer Next, Elegoo Slicer and Snapmaker Orca slicer options ([9dd3e69](https://github.com/TautvydasDerzinskas/Thingport/commit/9dd3e693e09efadb958b7ed31713310aad99f9c8))
* add author hover popover preview card ([864ec1c](https://github.com/TautvydasDerzinskas/Thingport/commit/864ec1cacdcf85a2f49a3ac64054178739ee36c5))
* add author linking admin trigger ([2a3434f](https://github.com/TautvydasDerzinskas/Thingport/commit/2a3434f126a92eb44e4ee633394146e8942f2a9a))
* add author page ([45b6bac](https://github.com/TautvydasDerzinskas/Thingport/commit/45b6bac574c69e376f982c18c71f7a3306176cd0))
* add captcha options for changing password and email ([21f91d6](https://github.com/TautvydasDerzinskas/Thingport/commit/21f91d62758e894488a18663adecc998f1a207a6))
* add collections ([b5568d3](https://github.com/TautvydasDerzinskas/Thingport/commit/b5568d35e61734f18504ddf697a8a78bf5521da6))
* add consume folder support ([e22f579](https://github.com/TautvydasDerzinskas/Thingport/commit/e22f57903f3c3f564e92a085eef99c4877127723))
* add first version of search ([83e0beb](https://github.com/TautvydasDerzinskas/Thingport/commit/83e0bebf45836017c3181b7ded881153b7e84451))
* add flaresolverr ([d8c2ef2](https://github.com/TautvydasDerzinskas/Thingport/commit/d8c2ef20ffe226df89c2a5bc64124d73aa5c17ec))
* add proper auth ([be45bac](https://github.com/TautvydasDerzinskas/Thingport/commit/be45bacbea7e313253c4cccc0a3dc633ad3b2876))
* add rich text formatting toolbar to model descriptions ([d49d7c9](https://github.com/TautvydasDerzinskas/Thingport/commit/d49d7c99196633d85b7ae3d375edd5f45e919829))
* add sanitized bambu 3mf open option ([0d8cd62](https://github.com/TautvydasDerzinskas/Thingport/commit/0d8cd62fa7837875591cad5bd58bd968bd7862e1))
* add setting to customize dashboard model thumbnail appearance ([163d73f](https://github.com/TautvydasDerzinskas/Thingport/commit/163d73f2a79b6e1a5c3721b996aef7c8310c93bf))
* add sorting and ect ([312c6be](https://github.com/TautvydasDerzinskas/Thingport/commit/312c6be706ec3f49356f71cb933bc78d0d64b71e))
* add tags route ([6990c2f](https://github.com/TautvydasDerzinskas/Thingport/commit/6990c2ff9f200ebd27c4deaafd47e0c3867b849c))
* add to collections modals ([1d8443e](https://github.com/TautvydasDerzinskas/Thingport/commit/1d8443e069a3bce13692f1d64cd071f8c6edf46c))
* add users activity page ([6533781](https://github.com/TautvydasDerzinskas/Thingport/commit/6533781a2141e720e953089a5fd55c2ddc5c4685))
* admin panel remake ([2bce5a2](https://github.com/TautvydasDerzinskas/Thingport/commit/2bce5a20497e8523f9d73fba83e30c3cb2f1917f))
* admin sidebar change and system health check view ([#48](https://github.com/TautvydasDerzinskas/Thingport/issues/48)) ([92161f8](https://github.com/TautvydasDerzinskas/Thingport/commit/92161f8cf801ea57ac229cf91e07190417e7b216))
* administration settings remake + OIDC support ([#49](https://github.com/TautvydasDerzinskas/Thingport/issues/49)) ([9a22386](https://github.com/TautvydasDerzinskas/Thingport/commit/9a2238691d8b079adf7bfb4becebc9cf01cb6cad))
* **admin:** manage user roles and delete users, with an instance owner ([9d41c4d](https://github.com/TautvydasDerzinskas/Thingport/commit/9d41c4dee3333677b964d2d0baede8ce45d5aa45))
* AI features split, categorisation UX updates ([e542cc4](https://github.com/TautvydasDerzinskas/Thingport/commit/e542cc4473cb57ad5281b06d15518e10ade8f843))
* **ai:** accept the provider base URL with or without /v1 ([29c54ba](https://github.com/TautvydasDerzinskas/Thingport/commit/29c54bac117077e9ee2dabed068baf6dfb56386b))
* **AI:** add improved descriptions ([97f17e4](https://github.com/TautvydasDerzinskas/Thingport/commit/97f17e4fa35aa03db4ce8ac17b8419100efc333c))
* allow bookmarking collections ([4f40803](https://github.com/TautvydasDerzinskas/Thingport/commit/4f408031b43d97e7040df21ddbbf259bfce65456))
* allow disabling registrations + invitation system ([91ffbf5](https://github.com/TautvydasDerzinskas/Thingport/commit/91ffbf5441dec0bedde4fd901c1bdca18a2b7267))
* allow downloading collection and tag models in bulk ([d3c651c](https://github.com/TautvydasDerzinskas/Thingport/commit/d3c651c05d2fa0e16f55546189cd5965997fd216))
* allow import thingiverse likes & collections ([ac32d03](https://github.com/TautvydasDerzinskas/Thingport/commit/ac32d03071d139ec4a8bdaed0017686cd68d700f))
* allow multiple meta category ids ([8450885](https://github.com/TautvydasDerzinskas/Thingport/commit/8450885ea19df6e505c6b3d5c0f3f061c462b09a))
* allow open in Cura slicer ([e84fbca](https://github.com/TautvydasDerzinskas/Thingport/commit/e84fbca5f9bfc2040c86cb07ffe421c75bffd212))
* allow toggling off author previews per user ([711ece0](https://github.com/TautvydasDerzinskas/Thingport/commit/711ece0f62bff1c93f951024f5f98bac582e7dd2))
* anable complex model simplification ([7464583](https://github.com/TautvydasDerzinskas/Thingport/commit/746458378052fa228465261cceca1a71dea58c34))
* **api-tokens:** add per-user API tokens with generation and revocation ([469641d](https://github.com/TautvydasDerzinskas/Thingport/commit/469641de181b76bf463357548fa314b777ab1f4d))
* **auth:** add password reset flow ([3a05fae](https://github.com/TautvydasDerzinskas/Thingport/commit/3a05fae555d3a553196487930f636ade4f9348e8))
* author linking and other minor author changes ([589a5f4](https://github.com/TautvydasDerzinskas/Thingport/commit/589a5f464abdd675afe1ef8f63fe2ed843823043))
* browse private collections functionality ([b619084](https://github.com/TautvydasDerzinskas/Thingport/commit/b619084be7ed060d02cd6ba473a196e7ba0859de))
* bulk feature changes ([7d18539](https://github.com/TautvydasDerzinskas/Thingport/commit/7d185395a355f327472652a054ba4a6a01800ba6))
* **categories:** add toggle between categories and folders ([33400fa](https://github.com/TautvydasDerzinskas/Thingport/commit/33400fa12803e1e7588a13fb200061b916062b80))
* **categories:** allow moving subcategories between parent categories ([172270f](https://github.com/TautvydasDerzinskas/Thingport/commit/172270fce81f4f713b295bde33e3bd853fcbc582))
* **categories:** allow unlimited depth of categories ([04f3106](https://github.com/TautvydasDerzinskas/Thingport/commit/04f3106ce84f94c92a08b42fa2546c4e050c1f98))
* categorize models with an OpenAI-compatible AI provider ([#11](https://github.com/TautvydasDerzinskas/Thingport/issues/11)) ([708a938](https://github.com/TautvydasDerzinskas/Thingport/commit/708a93822a40a69249232f52de8296006c33b7ae))
* chrome estensions Thingport grab ([7d53efb](https://github.com/TautvydasDerzinskas/Thingport/commit/7d53efb785469248b7d3be20fbf5af499a062090))
* collection impoort ([031cdf3](https://github.com/TautvydasDerzinskas/Thingport/commit/031cdf39902e212e24e0cb74d3cdbb8e7450a3a6))
* collection import pt2 ([f04ca0c](https://github.com/TautvydasDerzinskas/Thingport/commit/f04ca0c8b80bbc995084309c463896ffc32c7997))
* **collection-sync:** allow syncing collections with provider collections ([ef9152d](https://github.com/TautvydasDerzinskas/Thingport/commit/ef9152df6cd0edee4fff8355434c9e2e09f73731)), closes [#10](https://github.com/TautvydasDerzinskas/Thingport/issues/10)
* **collections:** add many models to a collection in one call ([acfa844](https://github.com/TautvydasDerzinskas/Thingport/commit/acfa844ebe62ee635941a2a6d499083cf4856d47))
* **collections:** turn sync on from Thingport, picking the provider's collection ([1131700](https://github.com/TautvydasDerzinskas/Thingport/commit/1131700ec5eb53801a85c842143717c66696d8d8))
* dashboard implementation ([cf5c8a9](https://github.com/TautvydasDerzinskas/Thingport/commit/cf5c8a958462bb0193379966696aa11935d72d1b))
* **dashboard:** add clock, weather, and featured-model widgets ([c71154a](https://github.com/TautvydasDerzinskas/Thingport/commit/c71154a83eb897122488a7c619cf38732eb4be44))
* **dashboard:** make dashboard panes toggleable ([3d1c851](https://github.com/TautvydasDerzinskas/Thingport/commit/3d1c851ad7baa007f883499d310c438f97c2b264))
* default categories for new users ([cefc27f](https://github.com/TautvydasDerzinskas/Thingport/commit/cefc27f23fd25e9693bcdc0f43b3e1b9c11f646c))
* edit model functionality ([37ac318](https://github.com/TautvydasDerzinskas/Thingport/commit/37ac318e40dff826d6081657cb59e4f3c30a4b5e))
* enable back flaresolverr ([ead9751](https://github.com/TautvydasDerzinskas/Thingport/commit/ead97510d4f4b39109e74f8921bc2b1fceb4dca3))
* extend dashboard settings with layouts ([2813237](https://github.com/TautvydasDerzinskas/Thingport/commit/2813237e037c9559b2d4beb161afffed5628c4b0))
* **extension:** improve loading messaging + make queue admin-only ([67a31cc](https://github.com/TautvydasDerzinskas/Thingport/commit/67a31cc94052fda9faf1daf831b6fbf5ce7b53e9))
* **flaresolverr:** make URL configurable in admin settings ([5fa6c40](https://github.com/TautvydasDerzinskas/Thingport/commit/5fa6c403247e497c0dece4e8e3e1d28d1e25b484))
* handle download limit error gracefully ([fd7c26a](https://github.com/TautvydasDerzinskas/Thingport/commit/fd7c26a760b82142b8be74634f1461e2007d5ab1))
* import all designer or all MakerWorld print profiles of a model ([101aa03](https://github.com/TautvydasDerzinskas/Thingport/commit/101aa03f9c7526287847afd60d8733dfb0125db5))
* import author details from makerworld ([b16c27b](https://github.com/TautvydasDerzinskas/Thingport/commit/b16c27bc1e4f107598824814a406043478ec609f))
* improve model details page ([d5db3d3](https://github.com/TautvydasDerzinskas/Thingport/commit/d5db3d3b18ca7844f4b2abda687b78757d8c0302))
* improve model details page ([05fae4c](https://github.com/TautvydasDerzinskas/Thingport/commit/05fae4c93fe9e466d3443f2a909df8c9298b7ee0))
* increase MakerWorld pacing ([fa75ae1](https://github.com/TautvydasDerzinskas/Thingport/commit/fa75ae1219334c98c675665ae5010d7c93cf176c))
* initial commit ([a8fef7d](https://github.com/TautvydasDerzinskas/Thingport/commit/a8fef7d4913d1096beaabc4cd78b9c3a6b7d3c86))
* link import queue with an admin page and send-to-queue in the extension, plus update from source ([#6](https://github.com/TautvydasDerzinskas/Thingport/issues/6)) ([96da36a](https://github.com/TautvydasDerzinskas/Thingport/commit/96da36ae7999ab5c91bf076a727922a0dbdad0ec))
* make print count be more interactive ([8e4f7dd](https://github.com/TautvydasDerzinskas/Thingport/commit/8e4f7ddf47de719b4da95753e1741e97f5de353c))
* make sure thingiverse token is verified ([9d07db9](https://github.com/TautvydasDerzinskas/Thingport/commit/9d07db9dc9c9cc3ef468ebdac96b9e2affe3132e))
* make ttl configurable in admin ([6c66e7b](https://github.com/TautvydasDerzinskas/Thingport/commit/6c66e7b615e4ebb8d18feea00330636b533fdad7))
* **notifications:** reinvent notifications ([1408b09](https://github.com/TautvydasDerzinskas/Thingport/commit/1408b09c5989499b38ee0effd1b7c29661a233a5))
* pause guided MakerWorld imports on a CAPTCHA, and fix localized and long collection imports ([627a442](https://github.com/TautvydasDerzinskas/Thingport/commit/627a442d53a709f41e42bc508af7305aca5578a1))
* printables importing ([47a0ddd](https://github.com/TautvydasDerzinskas/Thingport/commit/47a0dddf9337e2624505bc2acf3be5e6e9b1033a))
* rebrand from PrintStash to Thingport ([56de86d](https://github.com/TautvydasDerzinskas/Thingport/commit/56de86d5b5367fe593587bee73c1ca730e356ae5))
* **search:** add ability to load search active views ([90a9942](https://github.com/TautvydasDerzinskas/Thingport/commit/90a9942d1b9966bdcf0558e8d5b986af79a625bf))
* **search:** add option to see all results ([ad27e95](https://github.com/TautvydasDerzinskas/Thingport/commit/ad27e950a9048a4e50ab67196fbd42d61db86f89))
* show available models in model input ([8718d82](https://github.com/TautvydasDerzinskas/Thingport/commit/8718d82ab3b4afe0565e0d0a8dddb6de540493fc))
* show model usage in memory size ([2813d47](https://github.com/TautvydasDerzinskas/Thingport/commit/2813d47049817697e3c74ba0db82217c2912111d))
* support Markdown with embedded images in model descriptions ([97f0eea](https://github.com/TautvydasDerzinskas/Thingport/commit/97f0eea4c267612c8b78546d43129550dfac4dc8))
* **sync:** notify on enable, change defaults to daily and designer profiles ([9334438](https://github.com/TautvydasDerzinskas/Thingport/commit/9334438a521a2a5f9a39f6af4d892ac2465c02ce))
* **sync:** pause syncs while a provider isn't connected, and hand back models blocked by it ([6993a4c](https://github.com/TautvydasDerzinskas/Thingport/commit/6993a4c4231b9e80db9eb13c27ab97fc89e9ac01))
* system notifications updates, Thingport grab in System health check, node 24+ ([#52](https://github.com/TautvydasDerzinskas/Thingport/issues/52)) ([358dfc1](https://github.com/TautvydasDerzinskas/Thingport/commit/358dfc1a03a178115642d41423f40586cd879b90))
* **tags:** add pagination, thumbnails, and tag deletion ([cdf0a53](https://github.com/TautvydasDerzinskas/Thingport/commit/cdf0a53251e1ef6d507b15735ad3cae7406b00de))
* various major UI & UX improvements ([7b1f718](https://github.com/TautvydasDerzinskas/Thingport/commit/7b1f718c74485b79c9117469ff35aa4c661f6829))

### Performance Improvements

* **tags:** render tag mosaics on the server and size pages to the screen ([eefbde1](https://github.com/TautvydasDerzinskas/Thingport/commit/eefbde1bb5c64bd0860e2613a79e768a0f0e6891))
2026-10-17 17:30:59 +02:00
Tautvydas Derzinskas 358dfc1a03 feat: system notifications updates, Thingport grab in System health check, node 24+ (#52)
* feat: update system notifications

* feat: add Thingport grab to system health check

* ci: upgrade to Node.js 24 and centralize version management
2026-10-17 10:44:13 +02:00
Tautvydas Derzinskas 0bc0f99482 Fix/various minor ux improvements (#51)
* fix: improve context menu interaction and update check display

Add reopenContextMenuBelow utility to close context menus when clicking
outside and forward the right-click event to underlying elements. This
prevents clicks from being lost when users right-click beside a menu.

Replace UpdateCheckSection status text with UpdateCheckAnimation, an
animated component showing orbiting models during checking and colored
status indicator bubbles after completion.

* feat: add admin pages to search

* feat: add internet check to system health
2026-10-17 09:26:10 +02:00
Tautvydas Derzinskas 9a2238691d feat: administration settings remake + OIDC support (#49)
* feat: expand storage usage reporting with disk breakdown

* feat: add providers admin view

* feat(storage): add background reorganization and admin browser

Adds background-driven storage reorganization for moving model files
when the storage template changes, with an admin interface to preview
changes, check impact, monitor progress, and browse the storage tree
built from plate records rather than filesystem walks.

* feat: new auth admin settings page + OIDC support

* test: fix failing test
2026-10-17 05:07:24 +02:00
Tautvydas Derzinskas 92161f8cf8 feat: admin sidebar change and system health check view (#48) 2026-10-16 18:23:26 +02:00
Tautvydas Derzinskas 731a2950be ci: enable semantic versioning on frontend and backend (#47) 2026-10-16 16:31:54 +02:00
Tautvydas Derzinskas 9ada95b0a2 fix: make link-authors test deterministic
The test was timing-dependent: it checked for a 409 while the first run
is still going, but completion depended on when the mock fetch resolved.
Replace the instant mock with a promise the test controls, making the
assertion deterministic. Also save/restore the Thingiverse access token
to prevent test isolation issues.
2026-10-15 13:14:56 +02:00
Tautvydas Derzinskas 9d41c4dee3 feat(admin): manage user roles and delete users, with an instance owner
Admins can now make members admins and delete members from the Users page.
The owner, the first admin, can also demote and delete other admins; nobody
can demote or delete the owner, or themselves. A migration adds the owner
flag and gives it to each existing instance's longest-standing admin, and
the first sign-up of a fresh instance takes an advisory lock so concurrent
sign-ups can't make two owners.

Deleting a user removes their models with every file, their tag mosaics and
storage folder, then the account. Roles are now read from the database on
each request, so a demotion or deletion takes effect at once. Both actions
are logged under the acting admin.
2026-10-15 12:47:06 +02:00
Tautvydas Derzinskas eefbde1bb5 perf(tags): render tag mosaics on the server and size pages to the screen
Each tag tile now loads one WebP built by the backend from its newest models'
pictures, instead of up to ten images laid out in the browser. Mosaics are
made on first request and cached under storage/tag-mosaics; their URL carries
a hash of the pictures in them, so tagging, untagging or a new render gives a
new URL with nothing to invalidate, and existing libraries need no backfill.

The summary joins pictures only for the requested page's tags, a single
tag's mosaic looks up just that tag's newest models, and the Tags page asks
for enough tags to fill the screen. Deleting a tag, or all of a user's
models, removes its mosaics.
2026-10-15 12:46:42 +02:00
Tautvydas Derzinskas cdf0a53251 feat(tags): add pagination, thumbnails, and tag deletion 2026-10-15 10:10:43 +02:00
Tautvydas Derzinskas ad27e950a9 feat(search): add option to see all results 2026-10-14 22:14:55 +02:00
Tautvydas Derzinskas c5e5ab460e fix: distinguish Thingiverse rate limits from auth errors and add AI run logging 2026-10-14 21:11:27 +02:00
Tautvydas Derzinskas 97f17e4fa3 feat(AI): add improved descriptions 2026-10-14 20:29:45 +02:00
Tautvydas Derzinskas bfc3fa0d72 fix(ai): disable categorization when last model is deleted
When the last AI model is deleted, categorization is now forced
off server-side, preventing it from silently restarting when a
new model is added. The frontend distinguishes between loading
and no connections, hiding the feature toggle instead of
disabling it, and removes the unused "Add a model first" message.
2026-10-14 15:54:47 +02:00
Tautvydas Derzinskas e542cc4473 feat: AI features split, categorisation UX updates 2026-10-14 15:43:23 +02:00
Tautvydas Derzinskas 56f173a20b feat: ability to link multiple AIs 2026-10-14 15:20:56 +02:00
Tautvydas Derzinskas 8718d82ab3 feat: show available models in model input 2026-10-14 14:43:08 +02:00
Tautvydas Derzinskas bf083bcb26 fix(import): limit manual CAPTCHA cooloff lifts to one per 5 minutes, require value on captcha keys 2026-10-14 14:43:08 +02:00
Tautvydas Derzinskas e15653ca56 refactor(AI): identify candidates by path and support background recategorization (#19)
Provider prompts now identify category candidates by label/path instead
of numeric index, with duplicate-path and fuzzy-match handling. Add
reasoning_effort toggle with automatic fallback for providers that
don't support it.

Replace blocking single-print recategorize with background-queued flow
backed by notifications. Extend bulk-run scope to include folders and
manual categories alongside existing filters.
2026-10-14 12:20:58 +02:00
Rui Valim d70dcfeac2 fix(import): stop flagging models that mention robots as a MakerWorld CAPTCHA, and let a manual retry try again (#18)
* fix(import): stop flagging models that mention robots as a MakerWorld CAPTCHA, and let a manual retry try again

isCaptchaChallenge looked for "captcha" or "robot" in every top-level string of a reply,
design titles and summaries included, so a model named "Robot ..." failed as a CAPTCHA on
every retry and started the 2h cooloff for every other import. Only a captcha key or the
reply's own error, message or msg text counts now.

The cooloff also failed a retry straight away after the user solved the puzzle in the
browser, which is what the error message tells them to do. Starting or retrying a queue job
by hand, a bulk start or retry, and POST /import/jobs/:id/retry now lift it. Automatic
collection syncs still respect it.

* feat(extension): offer "Add to the queue" when MakerWorld blocks an import

A CAPTCHA or the daily download limit won't clear by clicking Import again, so the error
panel lets an admin park the link in the queue with the same collection and profile scope.

* fix(import): let a queue job cut off by a restart be started or retried

A restart marks a running job ERROR with its links still PENDING or RUNNING. The queue page
only offered Start for PAUSED jobs and Retry for jobs with FAILED links, and the API agreed,
so such a job could never run again. The same held for a job whose runner crashed.

Start now takes an ERROR job with links waiting, and a retry reruns links an interrupted
run never reached even when none of them failed.
2026-10-14 10:18:48 +02:00
Rui Valim 748879311a fix(ai): explain answers cut off by the token limit, and log AI and import runs (#16)
* fix(ai): leave room for a full answer and explain a cut-off one

max_tokens 300 cut answers off once the reason filled its 300-character
limit, and the run showed JSON.parse's position instead of the cause.
Raise it to 1024 and turn a parse failure into a readable error, naming
the token limit when the provider reports finish_reason length.

* feat(backend): add a shared logger with levels and greppable fields

One line per event with a level, a scope and key=value fields, or one
JSON object per line with LOG_FORMAT=json. LOG_LEVEL drops lines below
it. Errors log their message, status and code, plus the stack at error
level, and bearer tokens are redacted. Nothing outside it changes yet.

* feat(ai,import): log categorization and import runs through the logger

A bulk AI run kept only its last error in memory, so which models failed
and why was lost. Each provider answer it can't use now logs the model,
finish_reason, completion and reasoning tokens and the end of the answer;
each model's outcome and the run's start and totals are logged too.

Collection, Thingiverse, Printables, profile and zip imports dropped a
failed model without a trace; they now log it with its reason, plus the
job's start and totals. The links runner's console lines move to the
logger.

* fix(ai): read an answer wrapped in markdown or prose

Xiaomi MiMo ignores response_format and sent the object in bold,
`**{...}**`, which failed as not valid JSON although the answer was
complete. When the whole text doesn't parse, try the outermost braces.
2026-10-13 21:29:49 +02:00
Paul TrainaandClaude Opus 5.5 d5ae80951c fix: skip a stale MakerWorld defaultInstanceId when picking the print profile (#15)
MakerWorld can leave a design's defaultInstanceId pointing at a print profile that no longer
exists. pickMakerworldInstanceId (extension) and makerworldInstanceIdFromNextData (backend)
returned it unchecked, so the download-link request went to the dead profile and MakerWorld
answered 403 "The client does not have access rights to the content." Use the default only when
it is still one of the design's instances, otherwise the first, as selectMakerworldProfiles
already does.

Fixes #14


Claude-Session: https://claude.ai/code/session_01KGCb65Zhzwd3daF862ZE6R

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 06:47:04 +02:00
Tautvydas Derzinskas 6993a4c423 feat(sync): pause syncs while a provider isn't connected, and hand back models blocked by it 2026-10-12 21:15:38 +02:00
Tautvydas Derzinskas 29c04d264e test: fix failing tests 2026-10-12 13:24:26 +02:00
Tautvydas Derzinskas b619084be7 feat: browse private collections functionality 2026-10-12 12:54:26 +02:00
Tautvydas Derzinskas 1131700ec5 feat(collections): turn sync on from Thingport, picking the provider's collection
Every collection's Sync configuration now works before it's synced: a
Browse tab lists the user's own collections on MakerWorld (through
their cookie, private ones included), Printables and Thingiverse (by a
username asked once), and takes any collection's link. Each provider's
collections are drawn in its own colours and manner.

On Printables and Thingiverse the collection's current models are
imported by the sync's first check. MakerWorld rate-limits bulk
imports, so there only models added from now on come in. Settings can
be picked before turning sync on.
2026-10-12 05:31:01 +02:00
Tautvydas Derzinskas 9334438a52 feat(sync): notify on enable, change defaults to daily and designer profiles 2026-10-12 04:08:24 +02:00
Tautvydas Derzinskas acfa844ebe feat(collections): add many models to a collection in one call
Add POST /collection/:id/items. Thingport Grab uses it to file a
MakerWorld collection's already-imported models instead of one request
per model, falling back on older instances.
2026-10-12 03:50:57 +02:00
Tautvydas Derzinskas 44c687b3ae fix(extension): check a MakerWorld collection against the library in one call
The collection panel sent one /import/status request per model, all at
once. When any failed it counted the model as new, so a collection
already imported could offer to import almost everything again.

Add POST /import/status/batch and use it, falling back to paced
per-model checks on older instances. A failed check now shows an error
instead of guessing.
2026-10-12 03:50:28 +02:00
Tautvydas Derzinskas 1408b09c59 feat(notifications): reinvent notifications 2026-10-11 23:20:21 +02:00
Tautvydas Derzinskas 5fcadfb179 fix(ai): show why a recategorization failed
The route replaced every provider error with a bare "AI provider failed",
so a stopped Ollama looked the same as a timeout or a bad answer. Pass on the
reason (the API key is already redacted) and log it.
2026-10-11 21:16:48 +02:00
Tautvydas Derzinskas 29c54bac11 feat(ai): accept the provider base URL with or without /v1
A base URL with no path, like Ollama's http://host:11434, gets /v1 added.
URLs that already have a path are kept, so OpenRouter (/api/v1) and Gemini
(/v1beta/openai) keep working. Saved values are normalized when read.
2026-10-11 21:16:37 +02:00
Tautvydas Derzinskas 5fa6c40324 feat(flaresolverr): make URL configurable in admin settings 2026-10-11 19:34:29 +02:00
Tautvydas Derzinskas b13d0bf597 refactor(dashboard): server-side weather, render priorities, and model query optimization
Move weather endpoints to the server with caching and rate-limiting. Prioritize
3D viewer renders over background thumbnails. Query featured models from database
instead of loading all into memory.
2026-10-11 00:08:23 +03:00
Tautvydas Derzinskas 163d73f2a7 feat: add setting to customize dashboard model thumbnail appearance 2026-10-10 23:22:02 +03:00
Tautvydas Derzinskas c71154a83e feat(dashboard): add clock, weather, and featured-model widgets 2026-10-10 23:13:56 +03:00
Tautvydas Derzinskas 2813237e03 feat: extend dashboard settings with layouts 2026-10-10 21:50:29 +03:00
Rui ValimandTautvydas Derzinskas 708a93822a feat: categorize models with an OpenAI-compatible AI provider (#11)
* feat: categorize models with an OpenAI-compatible AI provider

Models can now be sorted into the user's categories by any OpenAI-compatible
chat endpoint (llama.cpp, Ollama, vLLM, OpenAI, OpenRouter...), configured once
by an admin under settings: mode off/suggest/auto, confidence threshold,
categorize on import, concurrency, optional preview image.

Every print now records where its category came from (manual, site rule, AI,
or legacy for rows that predate this). AI never changes a manual choice: runs
and the import hook skip them, and a single-model request needs force. Folders
are never touched. Category changes go through one setPrintCategory path, so
the name check and file relocation stay shared, and AI writes are a
compare-and-set against what was read before the provider call, so an edit
made meanwhile wins.

Users get per-model recategorize, accept/reject of pending suggestions (a
rejected category is not offered again), and a background "recategorize all"
with scope flags, progress and cancel that stops after repeated provider
failures.

* feat: AI categorization settings, suggestions and bulk runs in the UI

Admin settings get an AI categorization section with a connection test and a
privacy note. The model menu offers "Recategorize with AI" (asking before it
overrides a manual category), the side panel shows a pending suggestion with
accept/reject and marks AI-set categories, and the models page has
"Recategorize all with AI" with scope, progress and cancel, plus a pending
suggestions list with bulk accept/reject.

* fix: keep suggestion actions from overlapping the reason

MUI's secondaryAction is absolutely positioned over a fixed padding, so the
two buttons covered a long reason. They now sit in the row, and wrap under
the text on narrow screens.

* fix: put the clear API key action inside the key field

A full-width outlined button under the field read as an empty input in an
error state. It is now a small action at the end of the field, and the
helper text says the key goes away on save once it's clicked.

* refactor: update AI categorization admin part

* refactor: move ai categorization buttons to categories manager modal

* fix: multiple smaller problems with AI categorization

---------

Co-authored-by: Tautvydas Derzinskas <tautvydasuk@gmail.com>
2026-10-10 20:59:52 +03:00
Tautvydas Derzinskas ef9152df6c feat(collection-sync): allow syncing collections with provider collections
Implements #10
2026-10-09 00:34:44 +02:00
Tautvydas Derzinskas 90a9942d1b feat(search): add ability to load search active views 2026-10-08 08:36:23 +02:00