feat: complete TASK-WP2-07 latest exports
This commit is contained in:
@@ -72,6 +72,17 @@ interface ProjectStateRow {
|
||||
state_version: number;
|
||||
}
|
||||
|
||||
interface LatestExportRow {
|
||||
byte_size: number;
|
||||
created_at: number;
|
||||
export_id: string;
|
||||
format: "jpg" | "png";
|
||||
pixel_height: number;
|
||||
pixel_width: number;
|
||||
sha256: string;
|
||||
state_version: number;
|
||||
}
|
||||
|
||||
function isProjectRatio(value: string): value is ProjectRatio {
|
||||
return projectRatios.includes(value as ProjectRatio);
|
||||
}
|
||||
@@ -510,6 +521,10 @@ export class ProjectService {
|
||||
const images = this.database.prepare(`
|
||||
SELECT image_id, generation_id, created_at FROM project_images WHERE project_id = ? ORDER BY created_at, rowid
|
||||
`).all(projectId) as ImageRow[];
|
||||
const latestExports = this.database.prepare(`
|
||||
SELECT export_id, format, sha256, byte_size, pixel_width, pixel_height, state_version, created_at
|
||||
FROM latest_exports WHERE project_id = ? ORDER BY format
|
||||
`).all(projectId) as LatestExportRow[];
|
||||
const summary = this.projectSummary(row, images.length, generations.at(-1)?.status ?? null);
|
||||
const projectState = this.readProjectState(projectId);
|
||||
return {
|
||||
@@ -519,6 +534,17 @@ export class ProjectService {
|
||||
draftPrompt: row.draft_prompt,
|
||||
generations: generations.map((generation) => this.generationView(generation)),
|
||||
images: images.map((image) => ({ createdAt: iso(image.created_at), generationId: image.generation_id, imageId: image.image_id })),
|
||||
latestExports: latestExports.map((item) => ({
|
||||
byteSize: item.byte_size,
|
||||
createdAt: iso(item.created_at),
|
||||
downloadUrl: `/api/v1/projects/${projectId}/latest-exports/${item.format}`,
|
||||
exportId: item.export_id,
|
||||
format: item.format,
|
||||
pixelHeight: item.pixel_height,
|
||||
pixelWidth: item.pixel_width,
|
||||
sha256: item.sha256,
|
||||
stateVersion: item.state_version,
|
||||
})),
|
||||
pixelHeight: row.pixel_height,
|
||||
pixelWidth: row.pixel_width,
|
||||
saveStatus: "saved" as const,
|
||||
@@ -748,6 +774,20 @@ export class ProjectService {
|
||||
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS project_resource_files_managed ON project_resource_files(managed_file_id, project_id);
|
||||
CREATE TABLE IF NOT EXISTS latest_exports (
|
||||
project_id TEXT NOT NULL,
|
||||
format TEXT NOT NULL CHECK (format IN ('jpg', 'png')),
|
||||
export_id TEXT NOT NULL UNIQUE,
|
||||
managed_file_id TEXT NOT NULL,
|
||||
state_version INTEGER NOT NULL CHECK (state_version >= 1),
|
||||
sha256 TEXT NOT NULL CHECK (length(sha256) = 64),
|
||||
byte_size INTEGER NOT NULL CHECK (byte_size > 0),
|
||||
pixel_width INTEGER NOT NULL CHECK (pixel_width > 0),
|
||||
pixel_height INTEGER NOT NULL CHECK (pixel_height > 0),
|
||||
created_at INTEGER NOT NULL,
|
||||
PRIMARY KEY (project_id, format),
|
||||
FOREIGN KEY (project_id) REFERENCES projects(project_id) ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE IF NOT EXISTS project_cleanup_queue (
|
||||
cleanup_id TEXT PRIMARY KEY,
|
||||
project_id TEXT NOT NULL UNIQUE,
|
||||
|
||||
Reference in New Issue
Block a user