mirror of
https://github.com/immich-app/immich.git
synced 2025-07-31 15:08:44 -04:00
fix(server): clear activity when asset is removed from album (#19019)
This commit is contained in:
parent
ed4c7817e7
commit
55fe67dd20
@ -7,6 +7,7 @@ import {
|
||||
ReactionType,
|
||||
createActivity as create,
|
||||
createAlbum,
|
||||
removeAssetFromAlbum,
|
||||
} from '@immich/sdk';
|
||||
import { createUserDto, uuidDto } from 'src/fixtures';
|
||||
import { errorDto } from 'src/responses';
|
||||
@ -342,5 +343,36 @@ describe('/activities', () => {
|
||||
|
||||
expect(status).toBe(204);
|
||||
});
|
||||
|
||||
it('should return empty list when asset is removed', async () => {
|
||||
const album3 = await createAlbum(
|
||||
{
|
||||
createAlbumDto: {
|
||||
albumName: 'Album 3',
|
||||
assetIds: [asset.id],
|
||||
},
|
||||
},
|
||||
{ headers: asBearerAuth(admin.accessToken) },
|
||||
);
|
||||
|
||||
await createActivity({ albumId: album3.id, assetId: asset.id, type: ReactionType.Like });
|
||||
|
||||
await removeAssetFromAlbum(
|
||||
{
|
||||
id: album3.id,
|
||||
bulkIdsDto: {
|
||||
ids: [asset.id],
|
||||
},
|
||||
},
|
||||
{ headers: asBearerAuth(admin.accessToken) },
|
||||
);
|
||||
|
||||
const { status, body } = await request(app)
|
||||
.get('/activities')
|
||||
.query({ albumId: album.id })
|
||||
.set('Authorization', `Bearer ${admin.accessToken}`);
|
||||
expect(status).toEqual(200);
|
||||
expect(body).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -0,0 +1,19 @@
|
||||
import { Kysely, sql } from 'kysely';
|
||||
|
||||
export async function up(db: Kysely<any>): Promise<void> {
|
||||
await sql`DELETE FROM activity AS a
|
||||
WHERE a."assetId" IS NOT NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM albums_assets_assets AS aaa
|
||||
WHERE a."albumId" = aaa."albumsId"
|
||||
AND a."assetId" = aaa."assetsId"
|
||||
);`.execute(db);
|
||||
await sql`ALTER TABLE "activity" ADD CONSTRAINT "fk_activity_album_asset_composite" FOREIGN KEY ("albumId", "assetId") REFERENCES "albums_assets_assets" ("albumsId", "assetsId") ON UPDATE NO ACTION ON DELETE CASCADE;`.execute(db);
|
||||
await sql`CREATE INDEX "IDX_86102d85cfa7f196073aebff68" ON "activity" ("albumId", "assetId")`.execute(db);
|
||||
}
|
||||
|
||||
export async function down(db: Kysely<any>): Promise<void> {
|
||||
await sql`DROP INDEX "IDX_86102d85cfa7f196073aebff68";`.execute(db);
|
||||
await sql`ALTER TABLE "activity" DROP CONSTRAINT "fk_activity_album_asset_composite";`.execute(db);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { UpdatedAtTrigger, UpdateIdColumn } from 'src/decorators';
|
||||
import { AlbumAssetTable } from 'src/schema/tables/album-asset.table';
|
||||
import { AlbumTable } from 'src/schema/tables/album.table';
|
||||
import { AssetTable } from 'src/schema/tables/asset.table';
|
||||
import { UserTable } from 'src/schema/tables/user.table';
|
||||
@ -7,6 +8,7 @@ import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
ForeignKeyColumn,
|
||||
ForeignKeyConstraint,
|
||||
Generated,
|
||||
Index,
|
||||
PrimaryGeneratedColumn,
|
||||
@ -27,6 +29,14 @@ import {
|
||||
name: 'CHK_2ab1e70f113f450eb40c1e3ec8',
|
||||
expression: `("comment" IS NULL AND "isLiked" = true) OR ("comment" IS NOT NULL AND "isLiked" = false)`,
|
||||
})
|
||||
@ForeignKeyConstraint({
|
||||
name: 'fk_activity_album_asset_composite',
|
||||
columns: ['albumId', 'assetId'],
|
||||
referenceTable: () => AlbumAssetTable,
|
||||
referenceColumns: ['albumsId', 'assetsId'],
|
||||
onUpdate: 'NO ACTION',
|
||||
onDelete: 'CASCADE',
|
||||
})
|
||||
export class ActivityTable {
|
||||
@PrimaryGeneratedColumn()
|
||||
id!: Generated<string>;
|
||||
|
Loading…
x
Reference in New Issue
Block a user