Add team list and joining
This commit is contained in:
@@ -88,6 +88,9 @@ app.post('/teams', authMiddleware, async (req: Request, res: Response) => {
|
||||
}
|
||||
try {
|
||||
const team = await teamService.addTeam({name, tag, description: description ?? ''});
|
||||
// @ts-ignore
|
||||
const userId = req.user.id;
|
||||
await teamService.addTeamMember(team.id, userId, 'owner');
|
||||
res.status(201).send(team);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
@@ -148,6 +151,60 @@ app.get('/teams/:id/tournaments', async (req: Request, res: Response) => {
|
||||
res.send(entries);
|
||||
});
|
||||
|
||||
app.get('/users/me/teams', authMiddleware, async (req: Request, res: Response) => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const userId = req.user.id;
|
||||
const teams = await teamService.getTeamsByUserId(userId);
|
||||
res.send(teams);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send({error: 'Failed to get user teams'});
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/teams/:id/members', authMiddleware, async (req: Request, res: Response) => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const userId = req.user.id;
|
||||
const teamId = +req.params.id;
|
||||
|
||||
const isInTeam = await teamService.isUserInTeam(teamId, userId);
|
||||
if (isInTeam) {
|
||||
return res.status(409).send({error: 'User is already a member of this team'});
|
||||
}
|
||||
|
||||
const member = await teamService.addTeamMember(teamId, userId, 'member');
|
||||
res.status(201).send(member);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send({error: 'Failed to join team'});
|
||||
}
|
||||
});
|
||||
|
||||
app.delete('/teams/:id/members/me', authMiddleware, async (req: Request, res: Response) => {
|
||||
try {
|
||||
// @ts-ignore
|
||||
const userId = req.user.id;
|
||||
const teamId = +req.params.id;
|
||||
await teamService.removeTeamMember(teamId, userId);
|
||||
res.status(200).send({message: 'Left team successfully'});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send({error: 'Failed to leave team'});
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/teams/:id/members', async (req: Request, res: Response) => {
|
||||
try {
|
||||
const members = await teamService.getTeamMembers(+req.params.id);
|
||||
res.send(members);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
res.status(400).send({error: 'Failed to get team members'});
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/register', async (req: Request, res: Response) => {
|
||||
const { username, password } = req.body;
|
||||
if (!username || !password) {
|
||||
|
||||
@@ -13,3 +13,11 @@ export interface TournamentTeam {
|
||||
registeredAt: string;
|
||||
}
|
||||
|
||||
export interface TeamMember {
|
||||
id: number;
|
||||
teamId: number;
|
||||
userId: number;
|
||||
role: 'owner' | 'member';
|
||||
joinedAt: string;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Team, TournamentTeam } from '../models/team';
|
||||
import { Team, TournamentTeam, TeamMember } from '../models/team';
|
||||
import { Database, RunResult } from 'sqlite3';
|
||||
|
||||
export class TeamService {
|
||||
@@ -26,6 +26,18 @@ export class TeamService {
|
||||
FOREIGN KEY (teamId) REFERENCES Teams (id) ON DELETE CASCADE,
|
||||
UNIQUE (tournamentId, teamId)
|
||||
)`);
|
||||
|
||||
this.db.run(`CREATE TABLE IF NOT EXISTS TeamMembers
|
||||
(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
teamId INTEGER NOT NULL,
|
||||
userId INTEGER NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'member',
|
||||
joinedAt TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
FOREIGN KEY (teamId) REFERENCES Teams (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (userId) REFERENCES Users (id) ON DELETE CASCADE,
|
||||
UNIQUE (teamId, userId)
|
||||
)`);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -145,5 +157,78 @@ export class TeamService {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
addTeamMember(teamId: number, userId: number, role: 'owner' | 'member' = 'member'): Promise<TeamMember> {
|
||||
return new Promise<TeamMember>((resolve, reject) => {
|
||||
const stmt = this.db.prepare(`INSERT INTO TeamMembers (teamId, userId, role) VALUES (?, ?, ?)`);
|
||||
stmt.run(teamId, userId, role, function (this: RunResult, err: Error | null) {
|
||||
if (err) return reject(err);
|
||||
resolve({
|
||||
id: (this as any).lastID,
|
||||
teamId,
|
||||
userId,
|
||||
role,
|
||||
joinedAt: new Date().toISOString(),
|
||||
});
|
||||
});
|
||||
stmt.finalize();
|
||||
});
|
||||
}
|
||||
|
||||
removeTeamMember(teamId: number, userId: number): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.run(
|
||||
`DELETE FROM TeamMembers WHERE teamId = ? AND userId = ?`,
|
||||
[teamId, userId],
|
||||
(err: Error | null) => {
|
||||
if (err) return reject(err);
|
||||
resolve();
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getTeamsByUserId(userId: number): Promise<Team[]> {
|
||||
return new Promise<Team[]>((resolve, reject) => {
|
||||
this.db.all(
|
||||
`SELECT t.*, tm.role, tm.joinedAt FROM Teams t
|
||||
INNER JOIN TeamMembers tm ON t.id = tm.teamId
|
||||
WHERE tm.userId = ?`,
|
||||
[userId],
|
||||
(err: Error | null, rows: Team[]) => {
|
||||
if (err) return reject(err);
|
||||
resolve(rows);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getTeamMembers(teamId: number): Promise<TeamMember[]> {
|
||||
return new Promise<TeamMember[]>((resolve, reject) => {
|
||||
this.db.all(
|
||||
`SELECT tm.*, u.username FROM TeamMembers tm
|
||||
INNER JOIN Users u ON tm.userId = u.id
|
||||
WHERE tm.teamId = ?`,
|
||||
[teamId],
|
||||
(err: Error | null, rows: TeamMember[]) => {
|
||||
if (err) return reject(err);
|
||||
resolve(rows);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
isUserInTeam(teamId: number, userId: number): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve, reject) => {
|
||||
this.db.get(
|
||||
`SELECT COUNT(*) as count FROM TeamMembers WHERE teamId = ? AND userId = ?`,
|
||||
[teamId, userId],
|
||||
(err: Error | null, row: any) => {
|
||||
if (err) return reject(err);
|
||||
resolve(row.count > 0);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,4 +90,17 @@ export class UserService {
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
getUserByUsername(username: string): Promise<User | undefined> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.db.get(
|
||||
'SELECT id, username FROM Users WHERE username = ?',
|
||||
[username],
|
||||
(err: Error | null, user: User | undefined) => {
|
||||
if (err) return reject(err);
|
||||
resolve(user);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user