feat: track RosterActivity in clan log
All checks were successful
Build / build (22) (push) Successful in 43s
Build / build (18) (push) Successful in 1m6s
Build / build (20) (push) Successful in 59s
Build / build (18) (pull_request) Successful in 44s
Build / build (20) (pull_request) Successful in 1m8s
Build / build (22) (pull_request) Successful in 56s

This commit is contained in:
Sainan 2025-03-13 16:50:19 +01:00
parent 3a995ef6d1
commit d04d4cce34
5 changed files with 60 additions and 15 deletions

View File

@ -1,22 +1,36 @@
import { Guild, GuildMember } from "@/src/models/guildModel"; import { Guild, GuildMember } from "@/src/models/guildModel";
import { getGuildClient, updateInventoryForConfirmedGuildJoin } from "@/src/services/guildService"; import { getGuildClient, updateInventoryForConfirmedGuildJoin } from "@/src/services/guildService";
import { getAccountIdForRequest } from "@/src/services/loginService"; import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
import { Types } from "mongoose"; import { Types } from "mongoose";
export const confirmGuildInvitationController: RequestHandler = async (req, res) => { export const confirmGuildInvitationController: RequestHandler = async (req, res) => {
const accountId = await getAccountIdForRequest(req); const account = await getAccountForRequest(req);
const guildMember = await GuildMember.findOne({ const guildMember = await GuildMember.findOne({
accountId: accountId, accountId: account._id,
guildId: req.query.clanId as string guildId: req.query.clanId as string
}); });
if (guildMember) { if (guildMember) {
guildMember.status = 0; guildMember.status = 0;
await guildMember.save(); await guildMember.save();
await updateInventoryForConfirmedGuildJoin(accountId, new Types.ObjectId(req.query.clanId as string));
await updateInventoryForConfirmedGuildJoin(
account._id.toString(),
new Types.ObjectId(req.query.clanId as string)
);
const guild = (await Guild.findOne({ _id: req.query.clanId as string }))!; const guild = (await Guild.findOne({ _id: req.query.clanId as string }))!;
guild.RosterActivity ??= [];
guild.RosterActivity.push({
dateTime: new Date(),
entryType: 6,
details: getSuffixedName(account)
});
await guild.save();
res.json({ res.json({
...(await getGuildClient(guild, accountId)), ...(await getGuildClient(guild, account._id.toString())),
InventoryChanges: { InventoryChanges: {
Recipes: [ Recipes: [
{ {

View File

@ -25,6 +25,13 @@ export const getGuildLogController: RequestHandler = async (req, res) => {
details: entry.details details: entry.details
}); });
}); });
guild.RosterActivity?.forEach(entry => {
log.RosterActivity.push({
dateTime: toMongoDate(entry.dateTime),
entryType: entry.entryType,
details: entry.details
});
});
guild.ClassChanges?.forEach(entry => { guild.ClassChanges?.forEach(entry => {
log.ClassChanges.push({ log.ClassChanges.push({
dateTime: toMongoDate(entry.dateTime), dateTime: toMongoDate(entry.dateTime),

View File

@ -1,9 +1,12 @@
import { GuildMember } from "@/src/models/guildModel"; import { GuildMember } from "@/src/models/guildModel";
import { Account } from "@/src/models/loginModel";
import { getGuildForRequest } from "@/src/services/guildService"; import { getGuildForRequest } from "@/src/services/guildService";
import { getInventory } from "@/src/services/inventoryService"; import { getInventory } from "@/src/services/inventoryService";
import { getAccountForRequest, getSuffixedName } from "@/src/services/loginService";
import { RequestHandler } from "express"; import { RequestHandler } from "express";
export const removeFromGuildController: RequestHandler = async (req, res) => { export const removeFromGuildController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req);
const guild = await getGuildForRequest(req); const guild = await getGuildForRequest(req);
// TODO: Check permissions // TODO: Check permissions
const payload = JSON.parse(String(req.body)) as IRemoveFromGuildRequest; const payload = JSON.parse(String(req.body)) as IRemoveFromGuildRequest;
@ -32,6 +35,25 @@ export const removeFromGuildController: RequestHandler = async (req, res) => {
} }
await GuildMember.deleteOne({ _id: guildMember._id }); await GuildMember.deleteOne({ _id: guildMember._id });
guild.RosterActivity ??= [];
if (account._id.equals(payload.userId)) {
// Leave
guild.RosterActivity.push({
dateTime: new Date(),
entryType: 7,
details: getSuffixedName(account)
});
} else {
// Kick
const kickee = (await Account.findOne({ _id: payload.userId }))!;
guild.RosterActivity.push({
dateTime: new Date(),
entryType: 12,
details: getSuffixedName(kickee) + "," + getSuffixedName(account)
});
}
await guild.save();
res.json({ res.json({
_id: payload.userId, _id: payload.userId,
ItemToRemove: "/Lotus/Types/Keys/DojoKey", ItemToRemove: "/Lotus/Types/Keys/DojoKey",

View File

@ -5,8 +5,8 @@ import {
IDojoDecoDatabase, IDojoDecoDatabase,
ILongMOTD, ILongMOTD,
IGuildMemberDatabase, IGuildMemberDatabase,
IGuildLogClassChange, IGuildLogEntryNumber,
IGuildLogTechChange, IGuildLogEntryString,
IGuildRank IGuildRank
} from "@/src/types/guildTypes"; } from "@/src/types/guildTypes";
import { Document, Model, model, Schema, Types } from "mongoose"; import { Document, Model, model, Schema, Types } from "mongoose";
@ -106,7 +106,7 @@ const defaultRanks: IGuildRank[] = [
} }
]; ];
const guildLogTechChangeSchema = new Schema<IGuildLogTechChange>( const guildLogEntryStringSchema = new Schema<IGuildLogEntryString>(
{ {
dateTime: Date, dateTime: Date,
entryType: Number, entryType: Number,
@ -115,7 +115,7 @@ const guildLogTechChangeSchema = new Schema<IGuildLogTechChange>(
{ _id: false } { _id: false }
); );
const guildLogClassChangeSchema = new Schema<IGuildLogClassChange>( const guildLogEntryNumberSchema = new Schema<IGuildLogEntryNumber>(
{ {
dateTime: Date, dateTime: Date,
entryType: Number, entryType: Number,
@ -146,8 +146,9 @@ const guildSchema = new Schema<IGuildDatabase>(
CeremonyContributors: { type: [Types.ObjectId], default: undefined }, CeremonyContributors: { type: [Types.ObjectId], default: undefined },
CeremonyResetDate: Date, CeremonyResetDate: Date,
CeremonyEndo: Number, CeremonyEndo: Number,
TechChanges: { type: [guildLogTechChangeSchema], default: undefined }, TechChanges: { type: [guildLogEntryStringSchema], default: undefined },
ClassChanges: { type: [guildLogClassChangeSchema], default: undefined } RosterActivity: { type: [guildLogEntryStringSchema], default: undefined },
ClassChanges: { type: [guildLogEntryNumberSchema], default: undefined }
}, },
{ id: false } { id: false }
); );

View File

@ -48,8 +48,9 @@ export interface IGuildDatabase {
CeremonyContributors?: Types.ObjectId[]; CeremonyContributors?: Types.ObjectId[];
CeremonyResetDate?: Date; CeremonyResetDate?: Date;
TechChanges?: IGuildLogTechChange[]; TechChanges?: IGuildLogEntryString[];
ClassChanges?: IGuildLogClassChange[]; RosterActivity?: IGuildLogEntryString[];
ClassChanges?: IGuildLogEntryNumber[];
} }
export interface ILongMOTD { export interface ILongMOTD {
@ -186,13 +187,13 @@ export interface ITechProjectDatabase extends Omit<ITechProjectClient, "Completi
CompletionDate?: Date; CompletionDate?: Date;
} }
export interface IGuildLogTechChange { export interface IGuildLogEntryString {
dateTime: Date; dateTime: Date;
entryType: number; entryType: number;
details: string; details: string;
} }
export interface IGuildLogClassChange { export interface IGuildLogEntryNumber {
dateTime: Date; dateTime: Date;
entryType: number; entryType: number;
details: number; details: number;