2025-11-26 19:23:42 +00:00
|
|
|
-- name: CreateFolder :one
|
|
|
|
|
INSERT INTO folders (path, parentId, clientId, createdBy)
|
|
|
|
|
VALUES ($1, $2, $3, $4)
|
|
|
|
|
RETURNING *;
|
|
|
|
|
|
|
|
|
|
-- name: GetFolderByID :one
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE id = $1;
|
|
|
|
|
|
|
|
|
|
-- name: GetFolderByPath :one
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE clientId = $1 AND path = $2;
|
|
|
|
|
|
|
|
|
|
-- name: GetFoldersByClientID :many
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE clientId = $1
|
|
|
|
|
ORDER BY path;
|
|
|
|
|
|
|
|
|
|
-- name: GetFoldersByParentID :many
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE parentId = $1
|
|
|
|
|
ORDER BY path;
|
|
|
|
|
|
|
|
|
|
-- name: RenameFolder :exec
|
|
|
|
|
UPDATE folders
|
|
|
|
|
SET path = $2
|
|
|
|
|
WHERE id = $1;
|
|
|
|
|
|
|
|
|
|
-- name: GetFolderTree :many
|
|
|
|
|
WITH RECURSIVE folder_tree AS (
|
|
|
|
|
-- Base case: start with the target folder
|
|
|
|
|
SELECT id, path, parentId, clientId, createdAt, createdBy
|
|
|
|
|
FROM folders
|
|
|
|
|
WHERE id = $1
|
|
|
|
|
|
|
|
|
|
UNION ALL
|
|
|
|
|
|
|
|
|
|
-- Recursive case: find all child folders
|
|
|
|
|
SELECT f.id, f.path, f.parentId, f.clientId, f.createdAt, f.createdBy
|
|
|
|
|
FROM folders f
|
|
|
|
|
INNER JOIN folder_tree ft ON f.parentId = ft.id
|
|
|
|
|
)
|
|
|
|
|
SELECT id, path, parentId, clientId, createdAt, createdBy
|
|
|
|
|
FROM folder_tree
|
|
|
|
|
ORDER BY path;
|
|
|
|
|
|
|
|
|
|
-- name: GetRootFolders :many
|
|
|
|
|
-- Returns folders with null parentId (should only be the "/" root folder for each client)
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE clientId = $1 AND parentId IS NULL
|
|
|
|
|
ORDER BY path;
|
|
|
|
|
|
|
|
|
|
-- name: GetTopLevelFolders :many
|
|
|
|
|
-- Returns folders that are direct children of the root folder "/"
|
|
|
|
|
-- These are the user-visible top-level folders (e.g., /folder1, /folder2)
|
|
|
|
|
SELECT f.* FROM folders f
|
|
|
|
|
INNER JOIN folders root ON f.parentId = root.id
|
|
|
|
|
WHERE f.clientId = $1 AND root.path = '/'
|
|
|
|
|
ORDER BY f.path;
|
|
|
|
|
|
|
|
|
|
-- name: GetClientRootFolder :one
|
|
|
|
|
-- Returns the root folder "/" for a client
|
|
|
|
|
SELECT * FROM folders
|
|
|
|
|
WHERE clientId = $1 AND path = '/';
|
|
|
|
|
|
|
|
|
|
-- name: GetDocumentsByFolder :many
|
|
|
|
|
SELECT * FROM documents
|
|
|
|
|
WHERE folderId = $1
|
|
|
|
|
ORDER BY id;
|
|
|
|
|
|
|
|
|
|
-- name: CountDocumentsByFolder :one
|
|
|
|
|
SELECT COUNT(*) as total FROM documents
|
|
|
|
|
WHERE folderId = $1;
|
|
|
|
|
|
|
|
|
|
-- name: GetFolderLabelCounts :many
|
|
|
|
|
SELECT dl.label, COUNT(DISTINCT dl.documentId) as count
|
|
|
|
|
FROM documents d
|
|
|
|
|
INNER JOIN documentLabels dl ON d.id = dl.documentId
|
|
|
|
|
WHERE d.folderId = $1
|
|
|
|
|
GROUP BY dl.label
|
|
|
|
|
ORDER BY dl.label;
|
|
|
|
|
|
|
|
|
|
-- name: UpsertFolder :one
|
|
|
|
|
-- Insert a folder if it doesn't exist, or return the existing one
|
|
|
|
|
-- Used for auto-creating folder hierarchies during document upload
|
|
|
|
|
INSERT INTO folders (path, parentId, clientId, createdBy)
|
|
|
|
|
VALUES ($1, $2, $3, $4)
|
|
|
|
|
ON CONFLICT (clientId, path) DO UPDATE SET path = EXCLUDED.path
|
|
|
|
|
RETURNING *;
|
2025-12-11 14:25:51 +00:00
|
|
|
|
|
|
|
|
-- name: GetDocumentsByFolderEnriched :many
|
|
|
|
|
-- Gets documents in a folder with all enriched metadata fields
|
|
|
|
|
SELECT
|
|
|
|
|
d.id,
|
|
|
|
|
d.hash,
|
|
|
|
|
d.folderId,
|
|
|
|
|
d.filename,
|
2026-01-12 17:46:07 +00:00
|
|
|
d.originalPath,
|
|
|
|
|
d.file_size_bytes
|
2025-12-11 14:25:51 +00:00
|
|
|
FROM documents d
|
|
|
|
|
WHERE d.folderId = $1
|
|
|
|
|
ORDER BY d.id;
|