feat: Add delete event functionality

- Add delete_event endpoint in backend-flask
- Add cascade delete-orphan to Event model relationship
master
John Montagu, the 4th Earl of Sandvich 2024-11-30 19:01:23 -08:00
parent 8527d874d0
commit bb82f20a47
Signed by: sandvich
GPG Key ID: 9A39BE37E602B22D
4 changed files with 60 additions and 22 deletions

View File

@ -110,6 +110,26 @@ export class DefaultService {
}, },
}); });
} }
/**
* delete_event <DELETE>
* @param eventId
* @returns void
* @throws ApiError
*/
public deleteEvent(
eventId: number,
): CancelablePromise<void> {
return this.httpRequest.request({
method: 'DELETE',
url: '/api/events/{event_id}',
path: {
'event_id': eventId,
},
errors: {
422: `Unprocessable Content`,
},
});
}
/** /**
* get_event <GET> * get_event <GET>
* @param eventId * @param eventId

View File

@ -7,22 +7,8 @@ import { computed, reactive } from "vue";
export const useTeamsEventsStore = defineStore("teamsEvents", () => { export const useTeamsEventsStore = defineStore("teamsEvents", () => {
const clientStore = useClientStore(); const clientStore = useClientStore();
const client = clientStore.client; const client = clientStore.client;
//const eventsStore = useEventsStore();
const teamEvents = reactive<{ [teamId: number]: EventWithPlayerSchema[] }>({ }); const teamEvents = reactive<{ [teamId: number]: EventWithPlayerSchema[] }>({ });
//const teamEvents = computed(() => {
// console.log("Recomputing teamEvents");
// // map events to objects with teamId as key, and array of events as value
// return eventsStore.events
// .reduce((acc, event) => {
// if (!acc[event.teamId]) {
// acc[event.teamId] = [];
// }
// acc[event.teamId].push(event);
// return acc;
// }, { } as { [teamId: number]: EventSchema[] });
//});
function fetchTeamEvents(teamId: number) { function fetchTeamEvents(teamId: number) {
return clientStore.call( return clientStore.call(
@ -35,8 +21,8 @@ export const useTeamsEventsStore = defineStore("teamsEvents", () => {
); );
} }
function attendEvent(eventId: number) { async function attendEvent(eventId: number) {
client.default.attendEvent(eventId) return client.default.attendEvent(eventId)
.then((response) => { .then((response) => {
let index = teamEvents[response.event.teamId] let index = teamEvents[response.event.teamId]
.findIndex((event) => event.event.id == response.event.id); .findIndex((event) => event.event.id == response.event.id);
@ -44,8 +30,8 @@ export const useTeamsEventsStore = defineStore("teamsEvents", () => {
}); });
} }
function unattendEvent(eventId: number) { async function unattendEvent(eventId: number) {
client.default.unattendEvent(eventId) return client.default.unattendEvent(eventId)
.then((response) => { .then((response) => {
let index = teamEvents[response.event.teamId] let index = teamEvents[response.event.teamId]
.findIndex((event) => event.event.id == response.event.id); .findIndex((event) => event.event.id == response.event.id);
@ -53,8 +39,11 @@ export const useTeamsEventsStore = defineStore("teamsEvents", () => {
}); });
} }
function deleteEvent(eventId: number) { async function deleteEvent(eventId: number) {
// TODO: implement return client.default.deleteEvent(eventId)
.then(() => {
});
} }
return { return {

View File

@ -102,6 +102,8 @@ def create_event(player_team: PlayerTeam, team_id: int, json: CreateEventJson, *
event.description = json.description event.description = json.description
event.start_time = json.start_time event.start_time = json.start_time
assert_team_authority(player_team)
db.session.add(event) db.session.add(event)
db.session.flush() db.session.flush()
db.session.refresh(event) db.session.refresh(event)
@ -270,7 +272,9 @@ def update_event(player: Player, event_id: int, json: UpdateEventJson, **_):
event = db.session.query(Event).where(Event.id == event_id).one_or_none() event = db.session.query(Event).where(Event.id == event_id).one_or_none()
if not event: if not event:
abort(404) abort(404)
assert_team_membership(player, event.team)
player_team = assert_team_membership(player, event.team)
assert_team_authority(player_team)
for player_event in event.players: for player_event in event.players:
player_team = player_event.player_team player_team = player_event.player_team
@ -288,3 +292,24 @@ def update_event(player: Player, event_id: int, json: UpdateEventJson, **_):
event.update_discord_message() event.update_discord_message()
return EventSchema.from_model(event).dict(by_alias=True), 200 return EventSchema.from_model(event).dict(by_alias=True), 200
@api_events.delete("/<int:event_id>")
@spec.validate(
resp=Response(
HTTP_204=None,
),
operation_id="delete_event",
)
@requires_authentication
def delete_event(player: Player, event_id: int, **_):
event = db.session.query(Event).where(Event.id == event_id).one_or_none()
if not event:
abort(404)
player_team = assert_team_membership(player, event.team)
assert_team_authority(player_team)
db.session.delete(event)
db.session.commit()
return make_response({ }, 204)

View File

@ -28,7 +28,11 @@ class Event(app_db.BaseModel):
discord_message_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True) discord_message_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
team: Mapped["Team"] = relationship("Team", back_populates="events") team: Mapped["Team"] = relationship("Team", back_populates="events")
players: Mapped[list["PlayerEvent"]] = relationship("PlayerEvent", back_populates="event") players: Mapped[list["PlayerEvent"]] = relationship(
"PlayerEvent",
back_populates="event",
cascade="all, delete-orphan"
)
__table_args__ = ( __table_args__ = (
UniqueConstraint("team_id", "name", "start_time"), UniqueConstraint("team_id", "name", "start_time"),