refactor: move asset stacks to their own entity (#6353)

* feat: auto-stack burst photos

* feat: move stacks to asset stack entity

* chore: pin node version with volta in server

* chore: update e2e cases

* chore: cleanup

* feat: migrate existing stacks

---------

Co-authored-by: Jason Rasmussen <jrasm91@gmail.com>
This commit is contained in:
Zack Pollard
2024-01-27 18:52:14 +00:00
committed by GitHub
parent c4b8c853bc
commit 25cad79657
29 changed files with 538 additions and 243 deletions
@@ -0,0 +1,19 @@
import { Column, Entity, JoinColumn, OneToMany, OneToOne, PrimaryGeneratedColumn } from 'typeorm';
import { AssetEntity } from './asset.entity';
@Entity('asset_stack')
export class AssetStackEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@OneToMany(() => AssetEntity, (asset) => asset.stack)
assets!: AssetEntity[];
@OneToOne(() => AssetEntity)
@JoinColumn()
//TODO: Add constraint to ensure primary asset exists in the assets array
primaryAsset!: AssetEntity;
@Column({ nullable: false })
primaryAssetId!: string;
}
+5 -8
View File
@@ -16,6 +16,7 @@ import {
import { AlbumEntity } from './album.entity';
import { AssetFaceEntity } from './asset-face.entity';
import { AssetJobStatusEntity } from './asset-job-status.entity';
import { AssetStackEntity } from './asset-stack.entity';
import { ExifEntity } from './exif.entity';
import { LibraryEntity } from './library.entity';
import { SharedLinkEntity } from './shared-link.entity';
@@ -34,7 +35,6 @@ export const ASSET_CHECKSUM_CONSTRAINT = 'UQ_assets_owner_library_checksum';
@Index('IDX_day_of_month', { synchronize: false })
@Index('IDX_month', { synchronize: false })
@Index('IDX_originalPath_libraryId', ['originalPath', 'libraryId'])
@Index(['stackParentId'])
// For all assets, each originalpath must be unique per user and library
export class AssetEntity {
@PrimaryGeneratedColumn('uuid')
@@ -157,14 +157,11 @@ export class AssetEntity {
faces!: AssetFaceEntity[];
@Column({ nullable: true })
stackParentId?: string | null;
stackId?: string | null;
@ManyToOne(() => AssetEntity, (asset) => asset.stack, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
@JoinColumn({ name: 'stackParentId' })
stackParent?: AssetEntity | null;
@OneToMany(() => AssetEntity, (asset) => asset.stackParent)
stack?: AssetEntity[];
@ManyToOne(() => AssetStackEntity, { nullable: true, onDelete: 'SET NULL', onUpdate: 'CASCADE' })
@JoinColumn()
stack?: AssetStackEntity | null;
@OneToOne(() => AssetJobStatusEntity, (jobStatus) => jobStatus.asset, { nullable: true })
jobStatus?: AssetJobStatusEntity;
+4
View File
@@ -54,6 +54,10 @@ export class ExifEntity {
@Column({ type: 'varchar', nullable: true })
livePhotoCID!: string | null;
@Index('IDX_auto_stack_id')
@Column({ type: 'varchar', nullable: true })
autoStackId!: string | null;
@Column({ type: 'varchar', nullable: true })
state!: string | null;
+4 -1
View File
@@ -1,13 +1,14 @@
import { GeodataAdmin2Entity } from '@app/infra/entities/geodata-admin2.entity';
import { ActivityEntity } from './activity.entity';
import { AlbumEntity } from './album.entity';
import { APIKeyEntity } from './api-key.entity';
import { AssetFaceEntity } from './asset-face.entity';
import { AssetJobStatusEntity } from './asset-job-status.entity';
import { AssetStackEntity } from './asset-stack.entity';
import { AssetEntity } from './asset.entity';
import { AuditEntity } from './audit.entity';
import { ExifEntity } from './exif.entity';
import { GeodataAdmin1Entity } from './geodata-admin1.entity';
import { GeodataAdmin2Entity } from './geodata-admin2.entity';
import { GeodataPlacesEntity } from './geodata-places.entity';
import { LibraryEntity } from './library.entity';
import { MoveEntity } from './move.entity';
@@ -27,6 +28,7 @@ export * from './album.entity';
export * from './api-key.entity';
export * from './asset-face.entity';
export * from './asset-job-status.entity';
export * from './asset-stack.entity';
export * from './asset.entity';
export * from './audit.entity';
export * from './exif.entity';
@@ -51,6 +53,7 @@ export const databaseEntities = [
AlbumEntity,
APIKeyEntity,
AssetEntity,
AssetStackEntity,
AssetFaceEntity,
AssetJobStatusEntity,
AuditEntity,