Path: blob/master/src/packages/next/pages/api/v2/projects/copy-path-status.ts
14425 views
/*1API endpoint to query the status of a copy_paths row submitted via2/api/v2/projects/copy-path with wait_until_done=false.34The frontend polls this until `finished` is set; then `copy_error` is5either null (success) or contains a human-readable description of what6went wrong on the project pod / manage side. We deliberately use7`copy_error` rather than `error` so the shared apiPost wrapper, which8throws on any top-level `error` field, doesn't conflate "the copy9failed" with "this status request failed" — the caller wants to10distinguish those.1112Auth: the requesting account must be a collaborator on the target13project that the copy was directed to. (Anonymous owners count, since14they are the sole collaborator on a freshly-created project they made15via "Use CoCalc Anonymously".)16*/1718import getAccountId from "lib/account/get-account";19import getPool from "@cocalc/database/pool";20import isCollaborator from "@cocalc/server/projects/is-collaborator";21import { isValidUUID } from "@cocalc/util/misc";22import getParams from "lib/api/get-params";2324export default async function handle(req, res) {25const { copy_id } = getParams(req);26try {27if (!isValidUUID(copy_id)) {28throw Error("copy_id must be a valid uuid");29}30const account_id = await getAccountId(req);31if (!account_id) {32throw Error("must be signed in");33}34const pool = getPool("short");35const { rows } = await pool.query(36"SELECT target_project_id, started, finished, error FROM copy_paths WHERE id=$1",37[copy_id],38);39if (rows.length === 0) {40throw Error("copy_id not found");41}42const row = rows[0];43if (44!(await isCollaborator({45account_id,46project_id: row.target_project_id,47}))48) {49throw Error("must be a collaborator on the target project");50}51res.json({52started: row.started,53finished: row.finished,54copy_error: row.error,55});56} catch (err) {57res.json({ error: `${err.message}` });58}59}606162