rojects/source/server/routes/projects.ts

68 lines
2.5 KiB
TypeScript
Raw Normal View History

import { Router } from 'express';
import { projects, projectMembers } from '../db';
import { requireAuth } from '../middleware/auth';
import { createProjectStorage } from '../storage';
2026-07-14 13:05:04 +00:00
import { isOwner, canView, getMemberRole } from '../projectAccess';
const router = Router();
2026-07-14 13:05:04 +00:00
router.use( requireAuth );
2026-07-14 13:05:04 +00:00
router.get( '/', ( req, res ) =>
{
const user = req.user!;
const visible = projects.all().filter( p =>
{
if ( isOwner( p, user ) ) return true;
return getMemberRole( projectMembers.forProject( p.id ), user ) !== null;
} );
res.json( visible );
} );
2026-07-14 13:05:04 +00:00
router.post( '/', ( req, res ) =>
{
const { name } = req.body as { name?: string };
2026-07-14 13:05:04 +00:00
if ( !name ) { res.status( 400 ).json( { error: 'Name required' } ); return; }
const project = projects.create( { name, owner_id: req.user!.userId } );
createProjectStorage( project.id );
res.json( project );
} );
router.delete( '/:id', ( req, res ) =>
{
const project = projects.findById( req.params.id );
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
projects.delete( req.params.id );
res.json( { ok: true } );
} );
router.get( '/:id/members', ( req, res ) =>
{
const project = projects.findById( req.params.id );
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
const members = projectMembers.forProject( req.params.id );
if ( !canView( project, members, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
res.json( members );
} );
router.post( '/:id/members', ( req, res ) =>
{
const project = projects.findById( req.params.id );
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
const { email, role } = req.body as { email?: string; role?: string };
if ( !email ) { res.status( 400 ).json( { error: 'email required' } ); return; }
res.json( projectMembers.add( { project_id: req.params.id, member_type: 'user', member_id: email, role: role ?? 'viewer' } ) );
} );
router.delete( '/:id/members/:memberId', ( req, res ) =>
{
const project = projects.findById( req.params.id );
if ( !project ) { res.status( 404 ).json( { error: 'Not found' } ); return; }
if ( !isOwner( project, req.user! ) ) { res.status( 403 ).json( { error: 'Forbidden' } ); return; }
projectMembers.remove( req.params.memberId );
res.json( { ok: true } );
} );
export default router;