feat: add image management functionality
- Implemented image folder repository with CRUD operations. - Added image reference repository for managing image references to articles. - Created image repository for handling image assets, including listing, inserting, updating, and deleting images. - Introduced image usage repository to track storage usage and quotas for tenants. - Added SQL queries for image assets, folders, references, and usage. - Developed image handler for HTTP endpoints to manage images and folders. - Created database migration scripts for image-related tables and structures.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
-- name: ListImageAssets :many
|
||||
SELECT id, tenant_id, folder_id, object_key, name, size_bytes, status, created_by, created_at, updated_at
|
||||
FROM image_assets
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL
|
||||
AND (
|
||||
sqlc.narg(folder_id)::BIGINT IS NULL
|
||||
OR (sqlc.narg(folder_id)::BIGINT = 0 AND folder_id IS NULL)
|
||||
OR folder_id = sqlc.narg(folder_id)::BIGINT
|
||||
)
|
||||
AND (sqlc.narg(search_query)::TEXT IS NULL OR name ILIKE '%' || sqlc.narg(search_query)::TEXT || '%')
|
||||
ORDER BY created_at DESC
|
||||
LIMIT sqlc.arg(page_size) OFFSET sqlc.arg(page_offset);
|
||||
|
||||
-- name: CountImageAssets :one
|
||||
SELECT COUNT(*)::INT AS total
|
||||
FROM image_assets
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL
|
||||
AND (
|
||||
sqlc.narg(folder_id)::BIGINT IS NULL
|
||||
OR (sqlc.narg(folder_id)::BIGINT = 0 AND folder_id IS NULL)
|
||||
OR folder_id = sqlc.narg(folder_id)::BIGINT
|
||||
)
|
||||
AND (sqlc.narg(search_query)::TEXT IS NULL OR name ILIKE '%' || sqlc.narg(search_query)::TEXT || '%');
|
||||
|
||||
-- name: GetImageAsset :one
|
||||
SELECT id, tenant_id, folder_id, object_key, name, size_bytes, status, created_by, created_at, updated_at
|
||||
FROM image_assets
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: InsertImageAsset :one
|
||||
INSERT INTO image_assets (tenant_id, folder_id, object_key, name, size_bytes, status, created_by)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.narg(folder_id), sqlc.arg(object_key), sqlc.arg(name), sqlc.arg(size_bytes), sqlc.arg(status), sqlc.arg(created_by))
|
||||
RETURNING id;
|
||||
|
||||
-- name: UpdateImageAssetStatus :exec
|
||||
UPDATE image_assets
|
||||
SET status = sqlc.arg(status), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: UpdateImageAssetDeleted :exec
|
||||
UPDATE image_assets
|
||||
SET status = 'deleted', deleted_at = NOW(), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: UpdateImageAssetName :exec
|
||||
UPDATE image_assets
|
||||
SET name = sqlc.arg(name), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: UpdateImageAssetFolder :exec
|
||||
UPDATE image_assets
|
||||
SET folder_id = sqlc.narg(folder_id), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: ListActiveImagesByFolder :many
|
||||
SELECT id, object_key, size_bytes
|
||||
FROM image_assets
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND folder_id = sqlc.arg(folder_id)
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL;
|
||||
|
||||
-- name: MarkImagesInFolderPendingDelete :exec
|
||||
UPDATE image_assets
|
||||
SET status = 'pending_delete', folder_id = NULL, updated_at = NOW()
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND folder_id = sqlc.arg(folder_id)
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL;
|
||||
|
||||
-- name: CountUncategorizedImages :one
|
||||
SELECT COUNT(*)::INT AS count
|
||||
FROM image_assets
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND folder_id IS NULL
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL;
|
||||
@@ -0,0 +1,35 @@
|
||||
-- name: ListImageFolders :many
|
||||
SELECT f.id, f.tenant_id, f.name, f.created_at, f.updated_at,
|
||||
COUNT(ia.id) FILTER (WHERE ia.status = 'active' AND ia.deleted_at IS NULL)::INT AS image_count
|
||||
FROM image_folders f
|
||||
LEFT JOIN image_assets ia ON ia.tenant_id = f.tenant_id AND ia.folder_id = f.id
|
||||
WHERE f.tenant_id = sqlc.arg(tenant_id)
|
||||
GROUP BY f.id
|
||||
ORDER BY f.name;
|
||||
|
||||
-- name: CreateImageFolder :one
|
||||
INSERT INTO image_folders (tenant_id, name)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(name))
|
||||
RETURNING id;
|
||||
|
||||
-- name: UpdateImageFolder :exec
|
||||
UPDATE image_folders
|
||||
SET name = sqlc.arg(name), updated_at = NOW()
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: GetImageFolder :one
|
||||
SELECT id, tenant_id, name, created_at, updated_at
|
||||
FROM image_folders
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: DeleteImageFolder :exec
|
||||
DELETE FROM image_folders
|
||||
WHERE id = sqlc.arg(id) AND tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: CountActiveImagesInFolder :one
|
||||
SELECT COUNT(*)::INT AS count
|
||||
FROM image_assets
|
||||
WHERE tenant_id = sqlc.arg(tenant_id)
|
||||
AND folder_id = sqlc.arg(folder_id)
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL;
|
||||
@@ -0,0 +1,27 @@
|
||||
-- name: ListImageReferences :many
|
||||
SELECT r.id, r.tenant_id, r.image_asset_id, r.article_id, r.ref_scope, r.created_at
|
||||
FROM image_asset_references r
|
||||
WHERE r.tenant_id = sqlc.arg(tenant_id) AND r.image_asset_id = sqlc.arg(image_asset_id);
|
||||
|
||||
-- name: CountImageReferences :one
|
||||
SELECT COUNT(*)::INT AS total
|
||||
FROM image_asset_references
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND image_asset_id = sqlc.arg(image_asset_id);
|
||||
|
||||
-- name: UpsertImageReference :exec
|
||||
INSERT INTO image_asset_references (tenant_id, image_asset_id, article_id, ref_scope)
|
||||
VALUES (sqlc.arg(tenant_id), sqlc.arg(image_asset_id), sqlc.arg(article_id), sqlc.arg(ref_scope))
|
||||
ON CONFLICT (image_asset_id, article_id, ref_scope) DO UPDATE SET updated_at = NOW();
|
||||
|
||||
-- name: DeleteImageReferencesByArticle :exec
|
||||
DELETE FROM image_asset_references
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND article_id = sqlc.arg(article_id);
|
||||
|
||||
-- name: DeleteImageReferencesByArticleScope :exec
|
||||
DELETE FROM image_asset_references
|
||||
WHERE tenant_id = sqlc.arg(tenant_id) AND article_id = sqlc.arg(article_id) AND ref_scope = sqlc.arg(ref_scope);
|
||||
|
||||
-- name: ListImageReferenceArticles :many
|
||||
SELECT DISTINCT r.article_id, r.ref_scope
|
||||
FROM image_asset_references r
|
||||
WHERE r.tenant_id = sqlc.arg(tenant_id) AND r.image_asset_id = sqlc.arg(image_asset_id);
|
||||
@@ -0,0 +1,15 @@
|
||||
-- name: EnsureImageStorageUsageRow :exec
|
||||
INSERT INTO tenant_image_storage_usage (tenant_id, used_bytes)
|
||||
VALUES (sqlc.arg(tenant_id), 0)
|
||||
ON CONFLICT (tenant_id) DO NOTHING;
|
||||
|
||||
-- name: GetImageStorageUsage :one
|
||||
SELECT used_bytes, updated_at
|
||||
FROM tenant_image_storage_usage
|
||||
WHERE tenant_id = sqlc.arg(tenant_id);
|
||||
|
||||
-- name: ReleaseImageStorageQuota :exec
|
||||
UPDATE tenant_image_storage_usage
|
||||
SET used_bytes = GREATEST(0, used_bytes - sqlc.arg(release_bytes)),
|
||||
updated_at = NOW()
|
||||
WHERE tenant_id = sqlc.arg(tenant_id);
|
||||
Reference in New Issue
Block a user