rspace-online/modules/rphotos/schemas.ts

91 lines
2.0 KiB
TypeScript

/**
* rPhotos Automerge document schemas.
*
* Syncs shared album curation and photo annotations across space members.
* Actual photo files remain on the Immich server; this doc manages
* which albums are shared and any collaborative annotations.
*
* DocId format: {space}:photos:albums
*/
import type { DocSchema } from '../../shared/local-first/document';
// ── Document types ──
export interface SharedAlbum {
id: string;
name: string;
description: string;
sharedBy: string | null;
sharedAt: number;
visibility?: import('../../shared/membrane').ObjectVisibility;
}
export interface SpaceAlbum {
id: string;
immichAlbumId: string;
name: string;
createdBy: string;
createdAt: number;
visibility?: import('../../shared/membrane').ObjectVisibility;
}
export interface PhotoAnnotation {
assetId: string;
note: string;
authorDid: string;
createdAt: number;
}
export interface PhotosDoc {
meta: {
module: string;
collection: string;
version: number;
spaceSlug: string;
createdAt: number;
};
enabled: boolean;
spaceAlbumId: string | null;
subAlbums: Record<string, SpaceAlbum>;
sharedAlbums: Record<string, SharedAlbum>;
annotations: Record<string, PhotoAnnotation>;
}
// ── Schema registration ──
export const photosSchema: DocSchema<PhotosDoc> = {
module: 'photos',
collection: 'albums',
version: 2,
init: (): PhotosDoc => ({
meta: {
module: 'photos',
collection: 'albums',
version: 2,
spaceSlug: '',
createdAt: Date.now(),
},
enabled: false,
spaceAlbumId: null,
subAlbums: {},
sharedAlbums: {},
annotations: {},
}),
migrate: (doc: any, _fromVersion: number) => {
if (!doc.sharedAlbums) doc.sharedAlbums = {};
if (!doc.annotations) doc.annotations = {};
if (doc.enabled === undefined) doc.enabled = false;
if (doc.spaceAlbumId === undefined) doc.spaceAlbumId = null;
if (!doc.subAlbums) doc.subAlbums = {};
doc.meta.version = 2;
return doc;
},
};
// ── Helpers ──
export function photosDocId(space: string) {
return `${space}:photos:albums` as const;
}