1
0
mirror of https://github.com/immich-app/immich.git synced 2025-07-02 05:44:37 +02:00
Commit Graph

1242 Commits

Author SHA1 Message Date
68f52818ae feat(server): separate face clustering job (#5598)
* separate facial clustering job

* update api

* fixed some tests

* invert clustering

* hdbscan

* update api

* remove commented code

* wip dbscan

* cleanup

removed cluster endpoint

remove commented code

* fixes

updated tests

minor fixes and formatting

fixed queuing

refinements

* scale search range based on library size

* defer non-core faces

* optimizations

removed unused query option

* assign faces individually for correctness

fixed unit tests

remove unused method

* don't select face embedding

update sql

linting

fixed ml typing

* updated job mock

* paginate people query

* select face embeddings because typeorm

* fix setting face detection concurrency

* update sql

formatting

linting

* simplify logic

remove unused imports

* more specific delete signature

* more accurate typing for face stubs

* add migration

formatting

* chore: better typing

* don't select embedding by default

remove unused import

* updated sql

* use normal try/catch

* stricter concurrency typing and enforcement

* update api

* update job concurrency panel to show disabled queues

formatting

* check jobId in queueAll

fix tests

* remove outdated comment

* better facial recognition icon

* wording

wording

formatting

* fixed tests

* fix

* formatting & sql

* try to fix sql check

* more detailed description

* update sql

* formatting

* wording

* update `minFaces` description

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
2024-01-18 00:08:48 -05:00
9a2fa21b28 fix(server): scale transcoded videos if dimensions are odd (#6461)
scale if odd resolution
2024-01-17 22:16:44 -05:00
d4146e3e6d feat(server): provide the ability to search archived photos (#6332)
* Feat: provide the ability to search archived photos

Adds a query parameter (`searchArchived`) to the search URL parameters
to allow the results to contain archived photos.

* chore: rename includeArchived => withArchived

* chore: open api

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-18 02:08:00 +00:00
f0b328fb6b feat(server, web): smart merge (#5796)
* pr feedback

* fix: tests

* update assets statistics

* pr feedback

* pr feedback

* fix: linter

* pr feedback

* fix: don't limit the smart merge

* pr feedback

* fix: server code

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-18 01:52:11 +00:00
c55503496f fix(server): set log level of immich-admin process in boostrap function (#6458)
* fix(server): set log level of immich-admin process in boostrap function

* Remove log
2024-01-17 16:47:46 -05:00
6f291006e4 fix(server): handle 5 digit years (#6457) 2024-01-17 16:08:38 -05:00
0350058689 fix(deps): update server (#6415)
* fix(deps): update server

* chore: fix tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-17 18:24:51 +00:00
78de4f1312 feat(mobile): quota (#6409)
* feat(mobile): quota

* openapi

* user entity update

* Render quota

* refresh usage upon opening the app bar

* stop backup when quota exceed
2024-01-16 20:08:31 -06:00
abce82e235 fix(server): enable/disable password login on truenas (#6433) 2024-01-16 16:40:09 -05:00
76b66e42e1 chore(deps): update base-image to v20240111 (major) (#6355)
chore(deps): update base-image to v20240111

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-16 11:09:59 -05:00
7fc1954e2a fix(server): add filename search (#6394)
Fixes https://github.com/immich-app/immich/issues/5982.

There are basically three options:

1. Search `originalFileName` by dropping a file extension from the query
(if present). Lower fidelity but very easy - just a standard index &
equality.
2. Search `originalPath` by adding an index on `reverse(originalPath)`
and using `starts_with(reverse(query) + "/", reverse(originalPath)`. A
weird index & query but high fidelity.
3. Add a new generated column called `originalFileNameWithExtension` or
something. More storage, kinda jank.

TBH, I think (1) is good enough and easy to make better in the future.
For example, if I search "DSC_4242.jpg", I don't really think it matters
if "DSC_4242.mov" also shows up.

edit: There's a fourth approach that we discussed a bit in Discord and
decided we could switch to it in the future: using a GIN. The minor
issue is that Postgres doesn't tokenize paths in a useful (they're a
single token and it won't match against partial components). We can
solve that by tokenizing it ourselves. For example:

```
immich=# with vecs as (select to_tsvector('simple', array_to_string(string_to_array('upload/library/sushain/2015/2015-08-09/IMG_275.JPG', '/'), ' ')) as vec)  select * from vecs where vec @@ phraseto_tsquery('simple', array_to_string(string_to_array('library/sushain', '/'), ' '));
                                      vec
-------------------------------------------------------------------------------
 '-08':6 '-09':7 '2015':4,5 'img_275.jpg':8 'library':2 'sushain':3 'upload':1
(1 row)
```

The query is also tokenized with the 'split-by-slash-join-with-space'
strategy. This strategy results in `IMG_275.JPG`, `2015`, `sushain` and
`library/sushain` matching. But, `08` and `IMG_275` do not match. The
former is because the token is `-08` and the latter because the
`img_275.jpg` token is matched against exactly.
2024-01-15 14:40:28 -06:00
984feafb90 fix(server): extract image description (#6344) 2024-01-15 11:19:41 -05:00
d096caccac chore(web): quota enhancement (#6371)
* chore(web): quota enhancement

* show quota in user table

* update quota for single user ioption

* Add a note how to set unlimited storage

* fixed deletion doesn't update quota

* refactor relation

* fixed test

* re-refactor

* update sql

* fix e2e test

* Update server/src/domain/user/user.service.ts

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>

* revert e2e test

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-15 09:04:29 -06:00
2a8cb70c98 fix(deps): update dependency geo-tz to v8 (#6388)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-15 08:27:59 -05:00
deb1f970a8 feat(server, web): quotas (#4471)
* feat: quotas

* chore: open api

* chore: update status box and upload error message

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-12 19:43:36 -05:00
f4edb6c4bd feat(server): track metadata extracted at (#6352) 2024-01-12 19:39:45 -05:00
2439c5ab57 refactor: open api (#6334) 2024-01-12 07:36:27 -05:00
902977f165 fix(server): exif gps decoding (#6138) 2024-01-10 07:36:54 -05:00
bf1dd36fa9 refactor(server): split api and jobs into separate e2e suites (#6307)
* refactor: domain and infra modules

* refactor(server): e2e tests
2024-01-09 23:04:16 -05:00
12dc7c48c9 refactor(server): domain and infra modules (#6301) 2024-01-09 17:07:01 -05:00
df59b2099f Version v1.92.1 2024-01-08 15:24:38 +00:00
7cc0904273 feat(server): disable onboarding when config file is set (#6256) 2024-01-08 09:22:26 -06:00
319ddfda53 Version v1.92.0 2024-01-08 05:19:11 +00:00
5a66314ead test: small improvements to database init tests (#6232) 2024-01-07 01:53:09 +00:00
e262298090 fix(server): Split database queries based on PostgreSQL bound params limit (#6034)
* fix(server): Split database queries based on PostgreSQL bound params limit

PostgreSQL uses a 16-bit integer to indicate the number of bound
parameters.

This means that the maximum number of parameters for any query is 65535.
Any query that tries to bind more than that (e.g. searching by a list of
IDs) requires splitting the query into multiple chunks.

This change includes refactoring every Repository that runs queries
using a list of ids, and either flattening or merging results.

Fixes #5788, #5997.

Also, potentially a fix for #4648 (at least based on
[this comment](https://github.com/immich-app/immich/issues/4648#issuecomment-1826134027)).

References:

* https://github.com/typeorm/typeorm/issues/7565
* [PostgreSQL message format - Bind](https://www.postgresql.org/docs/15/protocol-message-formats.html#PROTOCOL-MESSAGE-FORMATS-BIND)

* misc: Create Chunked decorator to simplify implementation

* feat: Add ChunkedArray/ChunkedSet decorators
2024-01-06 20:36:12 -05:00
6835d4519a feat(server): add postgres major version check (#6213)
* feat(server): Throw error when PostgreSQL version is not within the supported versions
The pgvecto.rs extension, though not distributed, can be built for PostgreSQL 12 and 13.
An installation of PostgreSQL 12 with the pgvecto.rs extensions installed will not be caught by immich.
This causes immich to attempt to run the database migrations without having a proper environment.
With assertPostgresql the server will throw an error if the PostgreSQL version is not within the supported range.

* Replaced assertion with lesser than comparison
As requested by @zackpollard

* Changed the comparison to use the minPostgresVersion variable.
If we define one we might as well use it. makes changing the versioning later easier

* Added two new tests, modified two existing tests

`should return if minimum supported PostgreSQL and vectors version are installed`:
Check if init returns properly and that getPostgresVersion is called twice

`should thrown an error if PostgreSQL version is below minimum supported version`:
Checks if the init function correctly returns an error

`should suggest image with postgres ${major} if database is ${major}`:
Modified to set MockResolvedValue instead of MockResolvedValueOnce. With the new check we get the PostgreSQL version twice. So it needs to be set during the entire test.

`should not suggest image if postgres version is not in 14, 15 or 16`:
Modified the bounds to [14, 18]. Because values below 14 now will not get called.
Also Modified to call `getPostgresVersion.MockResolvedValueOnce` for twice, because it gets called twice.

* Fixed two mistakes in the jest functions from previous commit #2abcb60

`should thrown an error if PostgreSQL version is below minimum supported version`:
The regex function I wrote mistakingly used the negate function which check that the error *did not* contain the phrase "PostgreSQL". Which is the opposite

`should not suggest image if postgres version is not in 14, 15 or 16`:
confused bounds for a normal javascript array. Changed the test to only check for values above 16. As values below 14 will get thrown out by test `should return if minimum supported PostgreSQL and vectors version are installed`

I apologise for the mistakes in my previous commit.

* Format fix

---------

Co-authored-by: max <wak@vanling.net>
2024-01-06 19:24:09 -05:00
41a32b4e6b feat(server): add rw2 support (#6231) 2024-01-06 23:58:04 +00:00
0750e13d3f chore(server): set onboarding for existing instances (#6229)
* chore(server): set onboarding for existing instances

* down
2024-01-06 22:18:42 +00:00
8921278447 fix(server): Execute query in AlbumRepository.removeAsset method (#6216)
The current `removeAsset` implementation just builds the query but does
not execute it. That also seems to be the reason the `@GenerateSql`
decorator was commented out.
2024-01-06 11:56:08 -06:00
d1e16025cf fix(server): Fix incorrect sorting with search (#6031)
The search results are not sorted by date causing confision.

Fixes #5916
2024-01-04 14:47:09 -06:00
4cf1e553d2 feat(server): in upload folder, split the files into folders based on the first four of the files uuid (#6175) 2024-01-04 14:45:16 -06:00
13ba83dce6 chore(server): better ML error messages (#5914)
Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
2024-01-04 21:34:50 +01:00
aefd93e43a feat(server): add env for reverse geocoding path (#6163)
* feat: add env for reverse geocoding path

* fix: quote in doc
2024-01-04 13:36:52 +00:00
18f59f78e3 feat(web): onboarding (#6066)
* feat(web): onboarding

* feat: openapi

* feat: modulization

* feat: page advancing

* Animation

* Add storage templaete settings

* sql

* more style

* Theme

* information and styling

* hide/show table

* Styling

* Update user property

* fix test

* fix test:

* fix e2e

* test

* Update web/src/lib/components/onboarding-page/onboarding-hello.svelte

Co-authored-by: bo0tzz <git@bo0tzz.me>

* naming

* use System Metadata

* better return type

* onboarding using server metadata

* revert previous changes in user entity

* sql

* test web

* fix test server

* server/web test

* more test

* consolidate color theme change logic

* consolidate save button to storage template

* merge main

* fix web

---------

Co-authored-by: bo0tzz <git@bo0tzz.me>
2024-01-04 05:28:32 +00:00
f8d64be13c feat(server)!: move welcome message to settings (#6157)
* feat(server): move welcome message to settings

* chore: open api
2024-01-04 05:00:17 +00:00
7b40c20ea5 chore(server): time bucket sql (#6156) 2024-01-03 22:32:52 -06:00
317adc5c28 feat(web,server): external domain setting (#6146)
* feat: external domain setting

* chore: open api

* mobile: handle serverconfig-externalDomain

---------

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
2024-01-03 21:54:48 -05:00
13fb32513c fix(deps): update server (#6119)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-03 17:41:30 -05:00
23b38a0474 fix(deps): update dependency @nestjs/schedule to v4 (#5348)
* fix(deps): update dependency @nestjs/schedule to v4

* fix: change CronJob in addCronJob to match new type required by nestjs schedule module

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Zack Pollard <zackpollard@ymail.com>
2024-01-01 22:25:25 -05:00
cc7ba3c21a feat(server): search across own+partner assets (#5966)
* feat(server): search across own+partner assets

* generate sql

* fix sql parameter
2024-01-01 17:25:22 -05:00
4a5b8c3770 feat(server): Enqueue jobs in bulk (#5974)
* feat(server): Enqueue jobs in bulk

The Job Repository now has a `queueAll` method, that enqueues messages
in bulk (using BullMQ's
[`addBulk`](https://docs.bullmq.io/guide/queues/adding-bulks)),
improving performance when many jobs must be enqueued within the same
operation.

Primary change is in `src/domain/job/job.service.ts`, and other services
have been refactored to use `queueAll` when useful.

As a simple local benchmark, triggering a full thumbnail generation
process over a library of ~1,200 assets and ~350 faces went from
**~600ms** to **~250ms**.

* fix: Review feedback
2024-01-01 15:45:42 -05:00
Jan
7dd88c4114 fix(server): sanitize storagelabel when creating a user #3346 (#5717)
* sanitize storagelabel when creating a user #3346

* code formatting
2024-01-01 15:37:39 -05:00
a53b2de3c4 chore(deps): update dependency @types/supertest to v6 (#6099)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 19:27:00 +00:00
cb3f18bb9f chore(deps): update base-image to v20231228 (#6095)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-01-01 13:44:02 -05:00
03eb5ffc5c refactor(server): simplify config init process (#5702) 2024-01-01 13:16:44 -05:00
0ed89e61ec fix: remove archived people from explore (#6091) 2024-01-01 11:07:42 -05:00
ca9cad20bc feat: storage template locking + fix for database locks (#6054)
* fix: locks need to be acquired and released using the same session

* feat: only allow a single storage template operation at a single time

this has been added to avoid possible rare race conditions where two files are moved at once to the same path with the same name, causing our duplicate iterator to not detect them and therefore both files will have the same name and overwrite eachother
2023-12-30 09:09:33 -06:00
2e38fa73bf feat: storage template file move hardening (#5917)
* fix: pgvecto.rs extension breaks typeorm schema:drop command

* fix: parse postgres bigints to javascript number types when selecting data

* feat: verify file size is the same as original asset after copying file for storage template job

* feat: allow disabling of storage template job, defaults to disabled for new instances

* fix: don't allow setting concurrency for storage template migration, can cause race conditions above 1

* feat: add checksum verification when file is copied for storage template job

* fix: extract metadata for assets that aren't visible on timeline
2023-12-29 18:41:33 +00:00
5f6bd4ae7e fix(server): Reduce number of bound parameters in Access queries (#6015)
* fix(server): Reduce number of bound parameters in Access queries

According to https://github.com/typeorm/typeorm/issues/7565, the
introduction of bulk queries for permission checks could quickly reach
the limit of 65536 bound parameters allowed by the PostgreSQL
connection.

To avoid reaching that limit, this first change refactors the Access
queries that are expanding the set of ids multiple times. For example,
`asset.checkSharedLinkAccess` expands the ids 4 times, so providing just
~16400 ids is enough to break the query.

Refactored queries:

* activity.checkCreateAccess

```sql
-- Before
SELECT "AlbumEntity"."id" AS "AlbumEntity_id"
FROM "albums" "AlbumEntity"
    LEFT JOIN "albums_shared_users_users" "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"
        ON "AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."albumsId"="AlbumEntity"."id"
    LEFT JOIN "users" "AlbumEntity__AlbumEntity_sharedUsers"
        ON "AlbumEntity__AlbumEntity_sharedUsers"."id"="AlbumEntity_AlbumEntity__AlbumEntity_sharedUsers"."usersId"
        AND ("AlbumEntity__AlbumEntity_sharedUsers"."deletedAt" IS NULL)
WHERE
    (
        (
            "AlbumEntity"."id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
            AND "AlbumEntity"."isActivityEnabled" = $11
            AND "AlbumEntity__AlbumEntity_sharedUsers"."id" = $12
        )
        OR (
            "AlbumEntity"."id" IN ($13, $14, $15, $16, $17, $18, $19, $20, $21, $22)
            AND "AlbumEntity"."isActivityEnabled" = $23
            AND "AlbumEntity"."ownerId" = $24
        )
    )
    AND "AlbumEntity"."deletedAt" IS NULL

-- After
SELECT "album"."id" AS "album_id"
FROM "albums" "album"
    LEFT JOIN "albums_shared_users_users" "album_sharedUsers"
        ON "album_sharedUsers"."albumsId"="album"."id"
    LEFT JOIN "users" "sharedUsers"
        ON "sharedUsers"."id"="album_sharedUsers"."usersId"
        AND "sharedUsers"."deletedAt" IS NULL
WHERE
    "album"."id" IN ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
    AND "album"."isActivityEnabled" = true
    AND (
        "album"."ownerId" = $11
        OR "sharedUsers"."id" = $12
    )
    AND "album"."deletedAt" IS NULL
```

* asset.checkAlbumAccess

```sql
-- Before
SELECT
    "asset"."id" AS "assetId",
    "asset"."livePhotoVideoId" AS "livePhotoVideoId"
FROM "albums" "album"
    INNER JOIN "albums_assets_assets" "album_asset"
        ON "album_asset"."albumsId"="album"."id"
    INNER JOIN "assets" "asset"
        ON "asset"."id"="album_asset"."assetsId"
        AND "asset"."deletedAt" IS NULL
    LEFT JOIN "albums_shared_users_users" "album_sharedUsers"
        ON "album_sharedUsers"."albumsId"="album"."id"
    LEFT JOIN "users" "sharedUsers"
        ON "sharedUsers"."id"="album_sharedUsers"."usersId"
        AND "sharedUsers"."deletedAt" IS NULL
WHERE
    (
        "album"."ownerId" = $1
        OR "sharedUsers"."id" = $2
    )
    AND (
        "asset"."id" IN ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12)
        OR "asset"."livePhotoVideoId" IN ($13, $14, $15, $16, $17, $18, $19, $20, $21, $22)
    )
    AND "album"."deletedAt" IS NULL

-- After
WITH "assetIds" AS (
    SELECT unnest(array[$1, $2, $3, $4, $5, $6, $7, $8, $9, $10])::uuid AS "id"
    FROM (SELECT 1 AS dummy_column) "dummy_table"
)
SELECT
    "asset"."id" AS "assetId",
    "asset"."livePhotoVideoId" AS "livePhotoVideoId"
FROM "albums" "album"
    INNER JOIN "albums_assets_assets" "album_asset"
        ON "album_asset"."albumsId"="album"."id"
    INNER JOIN "assets" "asset"
        ON "asset"."id"="album_asset"."assetsId"
        AND "asset"."deletedAt" IS NULL
    LEFT JOIN "albums_shared_users_users" "album_sharedUsers"
        ON "album_sharedUsers"."albumsId"="album"."id"
    LEFT JOIN "users" "sharedUsers"
        ON "sharedUsers"."id"="album_sharedUsers"."usersId"
        AND "sharedUsers"."deletedAt" IS NULL
WHERE
    (
        "album"."ownerId" = $11
        OR "sharedUsers"."id" = $12
    )
    AND (
        "asset"."id" IN (SELECT id FROM "assetIds")
        OR "asset"."livePhotoVideoId" IN (SELECT id FROM "assetIds")
    )
    AND "album"."deletedAt" IS NULL
```

* asset.checkSharedLinkAccess

```sql
-- Before
SELECT
    "assets"."id" AS "assetId",
    "assets"."livePhotoVideoId" AS "assetLivePhotoVideoId",
    "albumAssets"."id" AS "albumAssetId",
    "albumAssets"."livePhotoVideoId" AS "albumAssetLivePhotoVideoId"
FROM "shared_links" "sharedLink"
    LEFT JOIN "albums" "album"
        ON "album"."id"="sharedLink"."albumId"
        AND "album"."deletedAt" IS NULL
    LEFT JOIN "shared_link__asset" "assets_sharedLink"
        ON "assets_sharedLink"."sharedLinksId"="sharedLink"."id"
    LEFT JOIN "assets" "assets"
        ON "assets"."id"="assets_sharedLink"."assetsId"
        AND "assets"."deletedAt" IS NULL
    LEFT JOIN "albums_assets_assets" "album_albumAssets"
        ON "album_albumAssets"."albumsId"="album"."id"
    LEFT JOIN "assets" "albumAssets"
        ON "albumAssets"."id"="album_albumAssets"."assetsId"
        AND "albumAssets"."deletedAt" IS NULL
WHERE
    "sharedLink"."id" = $1
    AND (
        "assets"."id" IN ($2, $3, $4, $5, $6, $7, $8, $9, $10, $11)
        OR "albumAssets"."id" IN ($12, $13, $14, $15, $16, $17, $18, $19, $20, $21)
        OR "assets"."livePhotoVideoId" IN ($22, $23, $24, $25, $26, $27, $28, $29, $30, $31)
        OR "albumAssets"."livePhotoVideoId" IN ($32, $33, $34, $35, $36, $37, $38, $39, $40, $41)
    )

-- After
WITH "assetIds" AS (
    SELECT unnest(array[$1, $2, $3, $4, $5, $6, $7, $8, $9, $10])::uuid AS "id"
    FROM (SELECT 1 AS dummy_column) "dummy_table"
)
SELECT
    "assets"."id" AS "assetId",
    "assets"."livePhotoVideoId" AS "assetLivePhotoVideoId",
    "albumAssets"."id" AS "albumAssetId",
    "albumAssets"."livePhotoVideoId" AS "albumAssetLivePhotoVideoId"
FROM "shared_links" "sharedLink"
    LEFT JOIN "albums" "album"
        ON "album"."id"="sharedLink"."albumId"
        AND "album"."deletedAt" IS NULL
    LEFT JOIN "shared_link__asset" "assets_sharedLink"
        ON "assets_sharedLink"."sharedLinksId"="sharedLink"."id"
    LEFT JOIN "assets" "assets"
        ON "assets"."id"="assets_sharedLink"."assetsId"
        AND "assets"."deletedAt" IS NULL
    LEFT JOIN "albums_assets_assets" "album_albumAssets"
        ON "album_albumAssets"."albumsId"="album"."id"
    LEFT JOIN "assets" "albumAssets"
        ON "albumAssets"."id"="album_albumAssets"."assetsId"
        AND "albumAssets"."deletedAt" IS NULL
    WHERE
        "sharedLink"."id" = $11
        AND (
            "assets"."id" IN (SELECT id FROM "assetIds")
            OR "albumAssets"."id" IN (SELECT id FROM "assetIds")
            OR "assets"."livePhotoVideoId" IN (SELECT id FROM "assetIds")
            OR "albumAssets"."livePhotoVideoId" IN (SELECT id FROM "assetIds")
        )
```

* fix: Use array overlapping instead of CTEs
2023-12-27 23:50:54 -06:00
4fff2c75aa chore(deps): update base-image to v20231221 (#6029)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-12-27 23:47:27 -06:00