S16 postgresql opslag added
All checks were successful
Build, test and publish / verify (push) Successful in 7m31s

This commit is contained in:
2026-11-04 17:10:25 +01:00
parent f59cad115a
commit 694bf3fa86
89 changed files with 3087 additions and 252 deletions

View File

@@ -1,7 +1,7 @@
import { SchedulingRun } from './scheduling-status';
import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { forkJoin, Observable } from 'rxjs';
import { Observable, tap } from 'rxjs';
import {
Coach,
DanceGroup,
@@ -20,64 +20,114 @@ import {
export class SchoolApi {
private readonly http = inject(HttpClient);
private readonly base = '/api/dance-schools';
private readonly revisions = new Map<number, number>();
schools(): Observable<School[]> {
return this.http.get<School[]>(this.base);
return this.http.get<School[]>(this.base).pipe(
tap((schools) => {
for (const school of schools) this.revisions.set(school.id, school.revision);
}),
);
}
schoolData(schoolId: number): Observable<SchoolData> {
const base = `${this.base}/${schoolId}`;
return forkJoin({
school: this.http.get<School>(base),
dancers: this.http.get<Dancer[]>(`${base}/dancers`),
groups: this.http.get<DanceGroup[]>(`${base}/dance-groups`),
shows: this.http.get<Show[]>(`${base}/shows`),
coaches: this.http.get<Coach[]>(`${base}/coaches`),
});
return this.http
.get<SchoolData>(`${this.base}/${schoolId}/data`)
.pipe(tap((data) => this.revisions.set(schoolId, data.school.revision)));
}
saveSchool(body: SchoolRequest, id?: number): Observable<School> {
private options(schoolId: number, expected?: number): { headers: Record<string, string> } {
const revision = expected ?? this.revisions.get(schoolId);
return { headers: revision === undefined ? {} : { 'X-School-Revision': String(revision) } };
}
saveSchool(body: SchoolRequest, id?: number, revision?: number): Observable<School> {
return id === undefined
? this.http.post<School>(this.base, body)
: this.http.put<School>(`${this.base}/${id}`, body);
: this.http.put<School>(`${this.base}/${id}`, body, this.options(id, revision));
}
saveDancer(schoolId: number, body: DancerRequest, id?: number): Observable<Dancer> {
return this.save(`${this.base}/${schoolId}/dancers`, body, id);
saveDancer(
schoolId: number,
body: DancerRequest,
id?: number,
revision?: number,
): Observable<Dancer> {
return this.save(`${this.base}/${schoolId}/dancers`, body, schoolId, id, revision);
}
saveGroup(schoolId: number, body: GroupRequest, id?: number): Observable<DanceGroup> {
return this.save(`${this.base}/${schoolId}/dance-groups`, body, id);
saveGroup(
schoolId: number,
body: GroupRequest,
id?: number,
revision?: number,
): Observable<DanceGroup> {
return this.save(`${this.base}/${schoolId}/dance-groups`, body, schoolId, id, revision);
}
saveShow(schoolId: number, body: ShowRequest, id?: number): Observable<Show> {
return this.save(`${this.base}/${schoolId}/shows`, body, id);
saveShow(schoolId: number, body: ShowRequest, id?: number, revision?: number): Observable<Show> {
return this.save(`${this.base}/${schoolId}/shows`, body, schoolId, id, revision);
}
schedule(schoolId: number, showId: number): Observable<SchedulingRun> {
return this.http.post<SchedulingRun>(`${this.base}/${schoolId}/shows/${showId}/schedule`, null);
return this.http.post<SchedulingRun>(
`${this.base}/${schoolId}/shows/${showId}/schedule`,
null,
this.options(schoolId),
);
}
saveAssignments(schoolId: number, showId: number, assignments: number[][]): Observable<Show> {
return this.http.put<Show>(`${this.base}/${schoolId}/shows/${showId}/assignments`, {
assignments,
});
saveAssignments(
schoolId: number,
showId: number,
assignments: number[][],
revision?: number,
): Observable<Show> {
return this.http.put<Show>(
`${this.base}/${schoolId}/shows/${showId}/assignments`,
{
assignments,
},
this.options(schoolId, revision),
);
}
finalize(schoolId: number, showId: number): Observable<Show> {
return this.http.post<Show>(`${this.base}/${schoolId}/shows/${showId}/finalize`, null);
finalize(schoolId: number, showId: number, revision?: number): Observable<Show> {
return this.http.post<Show>(
`${this.base}/${schoolId}/shows/${showId}/finalize`,
null,
this.options(schoolId, revision),
);
}
linkCoach(schoolId: number, dancerId: number, coachId?: number): Observable<Coach> {
return this.save<Coach>(`${this.base}/${schoolId}/coaches`, { dancerId }, coachId);
return this.save<Coach>(`${this.base}/${schoolId}/coaches`, { dancerId }, schoolId, coachId);
}
unlinkCoach(schoolId: number, coachId: number): Observable<void> {
return this.http.delete<void>(`${this.base}/${schoolId}/coaches/${coachId}/dancer`);
return this.http.delete<void>(
`${this.base}/${schoolId}/coaches/${coachId}/dancer`,
this.options(schoolId),
);
}
delete(kind: ResourceKind, schoolId: number, id: number): Observable<void> {
delete(kind: ResourceKind, schoolId: number, id: number, revision?: number): Observable<void> {
const collection = { school: '', dancer: '/dancers', group: '/dance-groups', show: '/shows' }[
kind
];
const url =
kind === 'school' ? `${this.base}/${id}` : `${this.base}/${schoolId}${collection}/${id}`;
return this.http.delete<void>(url);
return this.http.delete<void>(url, this.options(schoolId, revision));
}
membership(schoolId: number, groupId: number, dancerId: number, add: boolean): Observable<void> {
membership(
schoolId: number,
groupId: number,
dancerId: number,
add: boolean,
revision?: number,
): Observable<void> {
const url = `${this.base}/${schoolId}/dance-groups/${groupId}/dancers/${dancerId}`;
return add ? this.http.put<void>(url, null) : this.http.delete<void>(url);
return add
? this.http.put<void>(url, null, this.options(schoolId, revision))
: this.http.delete<void>(url, this.options(schoolId, revision));
}
private save<T>(url: string, body: unknown, id?: number): Observable<T> {
return id === undefined ? this.http.post<T>(url, body) : this.http.put<T>(`${url}/${id}`, body);
private save<T>(
url: string,
body: unknown,
schoolId: number,
id?: number,
revision?: number,
): Observable<T> {
return id === undefined
? this.http.post<T>(url, body, this.options(schoolId, revision))
: this.http.put<T>(`${url}/${id}`, body, this.options(schoolId, revision));
}
}