// @ts-check
/**
* Project controllers (contract envelope).
* @import {ExpressRequestAuthorized, ExpressResponse} from '../../types.js'
*/
import { sendOk, sendErrorFrom } from '../../utils/apiEnvelope.js';
import { hasActionPermission } from '../../utils/actionPermissions.js';
import { paginateList } from '../../utils/paginateList.js';
import * as service from './service.js';
/**
* @swagger
* /api/project/project/capabilities:
* get:
* summary: Capabilities of the caller (server-calculated)
* description: |
* Returns the capabilities of the currently authenticated user in the
* organization scope. Capabilities are always calculated server-side
* from job action rights — never from a client-supplied role or value.
* Currently exposes `projectCreate` (job action right `project.create`).
* tags:
* - Projects
* security:
* - bearerAuth: []
* responses:
* 200:
* description: Capabilities
* content:
* application/json:
* schema:
* type: object
* properties:
* success:
* type: boolean
* result:
* $ref: './project.swagger.yaml#/components/schemas/ProjectCapabilities'
* 403:
* description: Not authorized
*/
/**
* GET /project/project/capabilities
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const getProjectCapabilities = async (req, res) => {
try {
const projectCreate = await hasActionPermission(req, 'project.create');
sendOk(res, { projectCreate });
} catch (e) {
sendErrorFrom(res, e);
}
};
/**
* @swagger
* /api/project/project/{group}:
* put:
* summary: Create a project under a group
* description: |
* Creates a project in the current organization under the given group
* (`:group`). Requires the job action right `project.create` and change
* rights on the group. The creator receives admin on the new project.
* tags:
* - Projects
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: group
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ProjectCreateBody'
* responses:
* 200:
* description: Project created
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/SuccessResponse'
* 403:
* description: No project.create job action permission
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
* 422:
* description: Validation failed
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
*/
/**
* PUT /project/project/:group
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const putProject = async (req, res) => {
try {
const result = await service.createProject(req);
sendOk(res, result.result);
} catch (e) {
sendErrorFrom(res, e);
}
};
/**
* @swagger
* /api/project/project:
* get:
* summary: List projects
* description: |
* Lists all projects of the organization the caller can see
* (visible | changeable | admin). Admins and bots see all projects.
* Optional `group_uid` query filter restricts the listing to the projects
* of one owner group.
* tags:
* - Projects
* security:
* - bearerAuth: []
* parameters:
* - in: query
* name: group_uid
* required: false
* schema:
* type: string
* responses:
* 200:
* description: List of projects
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/SuccessResponse'
* 403:
* description: Not authorized
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
*/
/**
* GET /project/project
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const listProjects = async (req, res) => {
try {
if (req.query.__page) {
const result = await paginateList(req, async () => service.getListing(req.session, req.query));
sendOk(res, result);
return;
}
const result = await service.getListing(req.session, req.query);
sendOk(res, result);
} catch (e) {
sendErrorFrom(res, e);
}
};
/**
* @swagger
* /api/project/project/{UID}:
* get:
* summary: Get a project
* description: Requires at least `visible` on the project.
* tags:
* - Projects
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: UID
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Project
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/SuccessResponse'
* 403:
* description: Not accessible
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
* 404:
* description: Project not found in this organization
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
*/
/**
* GET /project/project/:UID
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const getProject = async (req, res) => {
try {
const result = await service.getProject(req, req.params.UID);
sendOk(res, result.result);
} catch (e) {
sendErrorFrom(res, e);
}
};
/**
* @swagger
* /api/project/project/{UID}:
* post:
* summary: Update project metadata
* description: Requires `admin` on the project. Only supplied fields are changed.
* tags:
* - Projects
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: UID
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ProjectUpdateBody'
* responses:
* 200:
* description: Project updated
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/SuccessResponse'
* 403:
* description: Not changeable
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
* delete:
* summary: Delete a project
* description: |
* Requires `admin` on the project. Removes the project, its memberA/member
* links (owner group, owner user and share links) in one transaction;
* orphaned shares (no remaining links) are deleted with it. Publishes
* remove events for the project and removed shares.
* tags:
* - Projects
* security:
* - bearerAuth: []
* parameters:
* - in: path
* name: UID
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Project deleted
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/SuccessResponse'
* 403:
* description: Not changeable
* content:
* application/json:
* schema:
* $ref: './project.swagger.yaml#/components/schemas/ErrorResponse'
*/
/**
* POST /project/project/:UID
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const updateProject = async (req, res) => {
try {
const result = await service.updateProject(req, req.params.UID);
sendOk(res, result.result);
} catch (e) {
sendErrorFrom(res, e);
}
};
/**
* DELETE /project/project/:UID
* @param {ExpressRequestAuthorized} req
* @param {ExpressResponse} res
*/
export const deleteProject = async (req, res) => {
try {
const result = await service.deleteProject(req, req.params.UID);
sendOk(res, result.result);
} catch (e) {
sendErrorFrom(res, e);
}
};