diff --git a/e2e/src/api/specs/stack.e2e-spec.ts b/e2e/src/api/specs/stack.e2e-spec.ts index 36b600bec9..91dd0d2a8e 100644 --- a/e2e/src/api/specs/stack.e2e-spec.ts +++ b/e2e/src/api/specs/stack.e2e-spec.ts @@ -172,4 +172,31 @@ describe('/stacks', () => { ); }); }); + + describe('GET /stacks/:id', () => { + it('should include exifInfo in stack assets', async () => { + const [asset1, asset2] = await Promise.all([ + utils.createAsset(user1.accessToken), + utils.createAsset(user1.accessToken), + ]); + + const stack = await utils.createStack(user1.accessToken, [asset1.id, asset2.id]); + + const { status, body } = await request(app) + .get(`/stacks/${stack.id}`) + .set('Authorization', `Bearer ${user1.accessToken}`); + + expect(status).toBe(200); + expect(body).toEqual( + expect.objectContaining({ + id: stack.id, + primaryAssetId: asset1.id, + assets: expect.arrayContaining([ + expect.objectContaining({ id: asset1.id, exifInfo: expect.any(Object) }), + expect.objectContaining({ id: asset2.id, exifInfo: expect.any(Object) }), + ]), + }), + ); + }); + }); }); diff --git a/server/src/queries/stack.repository.sql b/server/src/queries/stack.repository.sql index 54f86c94af..0fd1b233be 100644 --- a/server/src/queries/stack.repository.sql +++ b/server/src/queries/stack.repository.sql @@ -9,9 +9,18 @@ select from ( select - * + "assets".*, + to_json("exifInfo") as "exifInfo" from "assets" + inner join lateral ( + select + "exif".* + from + "exif" + where + "exif"."assetId" = "assets"."id" + ) as "exifInfo" on true where "assets"."deletedAt" is null and "assets"."stackId" = "asset_stack"."id" @@ -31,7 +40,7 @@ select from ( select - *, + "assets".*, ( select coalesce(json_agg(agg), '[]') @@ -45,9 +54,18 @@ select where "tag_asset"."assetsId" = "assets"."id" ) as agg - ) as "tags" + ) as "tags", + to_json("exifInfo") as "exifInfo" from "assets" + inner join lateral ( + select + "exif".* + from + "exif" + where + "exif"."assetId" = "assets"."id" + ) as "exifInfo" on true where "assets"."deletedAt" is null and "assets"."stackId" = "asset_stack"."id" @@ -67,7 +85,7 @@ select from ( select - *, + "assets".*, ( select coalesce(json_agg(agg), '[]') @@ -81,9 +99,18 @@ select where "tag_asset"."assetsId" = "assets"."id" ) as agg - ) as "tags" + ) as "tags", + to_json("exifInfo") as "exifInfo" from "assets" + inner join lateral ( + select + "exif".* + from + "exif" + where + "exif"."assetId" = "assets"."id" + ) as "exifInfo" on true where "assets"."deletedAt" is null and "assets"."stackId" = "asset_stack"."id" diff --git a/server/src/repositories/stack.repository.ts b/server/src/repositories/stack.repository.ts index 6a80c1f59c..018d7e77a4 100644 --- a/server/src/repositories/stack.repository.ts +++ b/server/src/repositories/stack.repository.ts @@ -12,7 +12,11 @@ const withAssets = (eb: ExpressionBuilder<DB, 'asset_stack'>, withTags = false) return jsonArrayFrom( eb .selectFrom('assets') - .selectAll() + .selectAll('assets') + .innerJoinLateral( + (eb) => eb.selectFrom('exif').selectAll('exif').whereRef('exif.assetId', '=', 'assets.id').as('exifInfo'), + (join) => join.onTrue(), + ) .$if(withTags, (eb) => eb.select((eb) => jsonArrayFrom( @@ -24,6 +28,7 @@ const withAssets = (eb: ExpressionBuilder<DB, 'asset_stack'>, withTags = false) ).as('tags'), ), ) + .select((eb) => eb.fn.toJson('exifInfo').as('exifInfo')) .where('assets.deletedAt', 'is', null) .whereRef('assets.stackId', '=', 'asset_stack.id'), ).as('assets');