- matrix-gateway: POST /internal/matrix/presence/online endpoint - usePresenceHeartbeat hook with activity tracking - Auto away after 5 min inactivity - Offline on page close/visibility change - Integrated in MatrixChatRoom component
157 lines
4.6 KiB
TypeScript
157 lines
4.6 KiB
TypeScript
/**
|
|
* Teams Routes (MicroDAO)
|
|
* Based on: api-mvp.md, updated for MicroDAO creation with balance checks
|
|
*
|
|
* Endpoints:
|
|
* - POST /api/v1/teams - Create MicroDAO (requires 1 DAARION on balance)
|
|
* - GET /api/v1/teams - List teams/MicroDAO
|
|
* - GET /api/v1/teams/:teamId - Get team/MicroDAO by ID
|
|
* - POST /api/v1/teams/:teamId/members - Invite member (requires balance check)
|
|
*/
|
|
|
|
import { Router } from 'express';
|
|
import { walletService } from '../../services/wallet/wallet.service';
|
|
import { daoFactoryService } from '../../services/dao-factory/dao-factory.service';
|
|
import type { CreateTeamRequest } from '../../../types/api';
|
|
|
|
export const teamsRoutes = Router();
|
|
|
|
// POST /api/v1/teams - Create MicroDAO
|
|
teamsRoutes.post('/', async (req, res) => {
|
|
try {
|
|
const userId = (req as any).userId;
|
|
const input: CreateTeamRequest = req.body;
|
|
|
|
// 1. Check wallet balance - need 1 DAARION on balance
|
|
const hasEnough = await walletService.hasEnoughForMicroDaoCreate(userId);
|
|
if (!hasEnough) {
|
|
res.status(403).json({
|
|
error: 'INSUFFICIENT_BALANCE',
|
|
message: 'Need 1 DAARION on balance to create MicroDAO',
|
|
required: { daarion: 1.0 },
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 2. Create MicroDAO through DAOFactory
|
|
const daoResult = await daoFactoryService.createDao(userId, {
|
|
name: input.name,
|
|
description: input.description,
|
|
type: input.mode === 'confidential' ? 'private' : 'public',
|
|
level: 'A4', // User-created MicroDAO are A4 level
|
|
});
|
|
|
|
// 3. TODO: Create team record in database
|
|
// For now, return DAO result
|
|
res.status(201).json({
|
|
id: daoResult.daoId,
|
|
name: input.name,
|
|
description: input.description,
|
|
mode: input.mode || 'public',
|
|
type: input.type || 'community',
|
|
created_at: new Date().toISOString(),
|
|
});
|
|
} catch (error: any) {
|
|
res.status(400).json({
|
|
error: error.message?.includes('INSUFFICIENT_BALANCE') ? 'INSUFFICIENT_BALANCE' : 'BAD_REQUEST',
|
|
message: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
// GET /api/v1/teams - List teams/MicroDAO
|
|
teamsRoutes.get('/', async (req, res) => {
|
|
try {
|
|
const userId = (req as any).userId;
|
|
|
|
// TODO: Get teams from database
|
|
// For now, return empty list
|
|
res.json({ teams: [] });
|
|
} catch (error: any) {
|
|
res.status(500).json({
|
|
error: 'INTERNAL_ERROR',
|
|
message: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
// GET /api/v1/teams/:teamId - Get team/MicroDAO by ID
|
|
teamsRoutes.get('/:teamId', async (req, res) => {
|
|
try {
|
|
const { teamId } = req.params;
|
|
|
|
// TODO: Get team from database
|
|
res.status(404).json({
|
|
error: 'NOT_FOUND',
|
|
message: `Team ${teamId} not found`,
|
|
});
|
|
} catch (error: any) {
|
|
res.status(500).json({
|
|
error: 'INTERNAL_ERROR',
|
|
message: error.message,
|
|
});
|
|
}
|
|
});
|
|
|
|
// POST /api/v1/teams/:teamId/members - Invite member
|
|
teamsRoutes.post('/:teamId/members', async (req, res) => {
|
|
try {
|
|
const userId = (req as any).userId; // Current user (admin)
|
|
const { teamId } = req.params;
|
|
const { email, role = 'member' } = req.body;
|
|
|
|
// 1. Check if current user is admin (has 1 DAARION)
|
|
const isAdmin = await walletService.hasEnoughForAdminRole(userId);
|
|
if (!isAdmin) {
|
|
res.status(403).json({
|
|
error: 'ACCESS_DENIED',
|
|
message: 'Need 1 DAARION on balance to invite members',
|
|
});
|
|
return;
|
|
}
|
|
|
|
// 2. Check invited user balance based on role
|
|
// TODO: Get invited user ID from email
|
|
const invitedUserId = `user_${email}`; // Placeholder
|
|
|
|
if (role === 'admin') {
|
|
// Admin role requires 1 DAARION
|
|
const hasEnough = await walletService.hasEnoughForAdminRole(invitedUserId);
|
|
if (!hasEnough) {
|
|
res.status(403).json({
|
|
error: 'INSUFFICIENT_BALANCE',
|
|
message: 'Invited user needs 1 DAARION on balance to be Admin',
|
|
required: { daarion: 1.0 },
|
|
});
|
|
return;
|
|
}
|
|
} else {
|
|
// Member role requires 0.01 DAARION
|
|
const hasEnough = await walletService.hasEnoughForMicroDaoUsage(invitedUserId);
|
|
if (!hasEnough) {
|
|
res.status(403).json({
|
|
error: 'INSUFFICIENT_BALANCE',
|
|
message: 'Invited user needs 0.01 DAARION on balance to use MicroDAO',
|
|
required: { daarion: 0.01 },
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 3. TODO: Create team member record in database
|
|
res.status(201).json({
|
|
team_id: teamId,
|
|
user_id: invitedUserId,
|
|
email,
|
|
role,
|
|
status: 'invited',
|
|
});
|
|
} catch (error: any) {
|
|
res.status(400).json({
|
|
error: 'BAD_REQUEST',
|
|
message: error.message,
|
|
});
|
|
}
|
|
});
|
|
|