diff --git a/.gitignore b/.gitignore
index 2b974d54a7ba5d8515a59218d3aadf0a6ff31d95..c089d3cf8f275d3a9fff33e23f7d56755894e3ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,5 +44,4 @@ __sapper__/
 .env.production.local
 
 # Frontend specific
-frontend/dist
-frontend/bindings
\ No newline at end of file
+frontend/dist
\ No newline at end of file
diff --git a/frontend/bindings/changeme/astro/services/club.ts b/frontend/bindings/changeme/astro/services/club.ts
new file mode 100644
index 0000000000000000000000000000000000000000..52026561280e12a5eb5694750523cbe998b1e7cc
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/club.ts
@@ -0,0 +1,23 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Call as $Call, Create as $Create} from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as $models from "./models.js";
+
+export function Load(): Promise<$models.Club[]> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(705761780) as any;
+    let $typingPromise = $resultPromise.then(($result) => {
+        return $$createType1($result);
+    }) as any;
+    $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
+    return $typingPromise;
+}
+
+// Private type creation functions
+const $$createType0 = $models.Club.createFrom;
+const $$createType1 = $Create.Array($$createType0);
diff --git a/frontend/bindings/changeme/astro/services/competition.ts b/frontend/bindings/changeme/astro/services/competition.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4d98980accafa2416b76ce98dd85c44fd5bdbf13
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/competition.ts
@@ -0,0 +1,55 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+/**
+ * Competition : Competition details
+ * @module
+ */
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Call as $Call, Create as $Create} from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as $models from "./models.js";
+
+export function AddPlayer(player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3220417277, player) as any;
+    return $resultPromise;
+}
+
+export function AddPlayerToStage(player: $models.Player, stage: $models.Stage): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2532203882, player, stage) as any;
+    return $resultPromise;
+}
+
+export function FinishCompetition(): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(826570137) as any;
+    return $resultPromise;
+}
+
+export function RemovePlayer(player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(1491269932, player) as any;
+    return $resultPromise;
+}
+
+export function RemovePlayerFromStage(player: $models.Player, stage: $models.Stage): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(362483458, player, stage) as any;
+    return $resultPromise;
+}
+
+export function StartCompetition(): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3322759170) as any;
+    return $resultPromise;
+}
+
+export function String(): Promise<string> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2560236652) as any;
+    return $resultPromise;
+}
+
+export function UpdatePlayer(player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(132875429, player) as any;
+    return $resultPromise;
+}
diff --git a/frontend/bindings/changeme/astro/services/index.ts b/frontend/bindings/changeme/astro/services/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..042303c127d1b5e9c78b9d8675b94d89c97abddb
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/index.ts
@@ -0,0 +1,15 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+import * as Competition from "./competition.js";
+import * as Player from "./player.js";
+import * as Pool from "./pool.js";
+import * as Session from "./session.js";
+export {
+    Competition,
+    Player,
+    Pool,
+    Session
+};
+
+export * from "./models.js";
diff --git a/frontend/bindings/changeme/astro/services/models.ts b/frontend/bindings/changeme/astro/services/models.ts
new file mode 100644
index 0000000000000000000000000000000000000000..dbf1e772d2927d7bb2bbfb8c60b1f0928853c09c
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/models.ts
@@ -0,0 +1,385 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Create as $Create} from "@wailsio/runtime";
+
+/**
+ * Category : Age category
+ */
+export enum Category {
+    /**
+     * The Go zero value for the underlying type of the enum.
+     */
+    $zero = 0,
+
+    /**
+     * 0
+     */
+    U7 = 0,
+
+    /**
+     * 1
+     */
+    U9 = 1,
+
+    /**
+     * 2
+     */
+    U11 = 2,
+
+    /**
+     * 3
+     */
+    U13 = 3,
+
+    /**
+     * 4
+     */
+    U15 = 4,
+
+    /**
+     * 5
+     */
+    U17 = 5,
+
+    /**
+     * 6
+     */
+    U20 = 6,
+
+    /**
+     * 7
+     */
+    SENIOR = 7,
+
+    /**
+     * 8
+     */
+    VETERAN = 8,
+};
+
+export class Club {
+    "club_id": number;
+    "club_name": string;
+
+    /** Creates a new Club instance. */
+    constructor($$source: Partial<Club> = {}) {
+        if (!("club_id" in $$source)) {
+            this["club_id"] = 0;
+        }
+        if (!("club_name" in $$source)) {
+            this["club_name"] = "";
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Club instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Club {
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        return new Club($$parsedSource as Partial<Club>);
+    }
+}
+
+/**
+ * Competition : Competition details
+ */
+export class Competition {
+    /**
+     * 255 competitions max
+     */
+    "CompetitionID": number;
+    "CompetitionName": string;
+    "CompetitionCategory": Category;
+    "CompetitionWeapon": Weapon;
+    "CompetitionState": State;
+    "CompetitionMaxStageNumber": number;
+    "CompetitionStages": { [_: `${number}`]: Stage | null };
+    "CompetitionPlayers": { [_: `${number}`]: Player | null };
+
+    /** Creates a new Competition instance. */
+    constructor($$source: Partial<Competition> = {}) {
+        if (!("CompetitionID" in $$source)) {
+            this["CompetitionID"] = 0;
+        }
+        if (!("CompetitionName" in $$source)) {
+            this["CompetitionName"] = "";
+        }
+        if (!("CompetitionCategory" in $$source)) {
+            this["CompetitionCategory"] = (0 as Category);
+        }
+        if (!("CompetitionWeapon" in $$source)) {
+            this["CompetitionWeapon"] = (0 as Weapon);
+        }
+        if (!("CompetitionState" in $$source)) {
+            this["CompetitionState"] = (0 as State);
+        }
+        if (!("CompetitionMaxStageNumber" in $$source)) {
+            this["CompetitionMaxStageNumber"] = 0;
+        }
+        if (!("CompetitionStages" in $$source)) {
+            this["CompetitionStages"] = {};
+        }
+        if (!("CompetitionPlayers" in $$source)) {
+            this["CompetitionPlayers"] = {};
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Competition instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Competition {
+        const $$createField6_0 = $$createType0;
+        const $$createField7_0 = $$createType3;
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        if ("CompetitionStages" in $$parsedSource) {
+            $$parsedSource["CompetitionStages"] = $$createField6_0($$parsedSource["CompetitionStages"]);
+        }
+        if ("CompetitionPlayers" in $$parsedSource) {
+            $$parsedSource["CompetitionPlayers"] = $$createField7_0($$parsedSource["CompetitionPlayers"]);
+        }
+        return new Competition($$parsedSource as Partial<Competition>);
+    }
+}
+
+export class Nation {
+    "nation_id": number;
+    "nation_name": string;
+    "nation_code": string;
+
+    /** Creates a new Nation instance. */
+    constructor($$source: Partial<Nation> = {}) {
+        if (!("nation_id" in $$source)) {
+            this["nation_id"] = 0;
+        }
+        if (!("nation_name" in $$source)) {
+            this["nation_name"] = "";
+        }
+        if (!("nation_code" in $$source)) {
+            this["nation_code"] = "";
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Nation instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Nation {
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        return new Nation($$parsedSource as Partial<Nation>);
+    }
+}
+
+/**
+ * Player : Person details
+ */
+export class Player {
+    /**
+     * More than 255 players
+     */
+    "PlayerID": number;
+    "PlayerFirstname": string;
+    "PlayerLastname": string;
+    "PlayerNation": Nation | null;
+    "PlayerRegion": Region | null;
+    "PlayerClub": Club | null;
+    "PlayerInitialRank": number;
+
+    /** Creates a new Player instance. */
+    constructor($$source: Partial<Player> = {}) {
+        if (!("PlayerID" in $$source)) {
+            this["PlayerID"] = 0;
+        }
+        if (!("PlayerFirstname" in $$source)) {
+            this["PlayerFirstname"] = "";
+        }
+        if (!("PlayerLastname" in $$source)) {
+            this["PlayerLastname"] = "";
+        }
+        if (!("PlayerNation" in $$source)) {
+            this["PlayerNation"] = null;
+        }
+        if (!("PlayerRegion" in $$source)) {
+            this["PlayerRegion"] = null;
+        }
+        if (!("PlayerClub" in $$source)) {
+            this["PlayerClub"] = null;
+        }
+        if (!("PlayerInitialRank" in $$source)) {
+            this["PlayerInitialRank"] = 0;
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Player instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Player {
+        const $$createField3_0 = $$createType5;
+        const $$createField4_0 = $$createType7;
+        const $$createField5_0 = $$createType9;
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        if ("PlayerNation" in $$parsedSource) {
+            $$parsedSource["PlayerNation"] = $$createField3_0($$parsedSource["PlayerNation"]);
+        }
+        if ("PlayerRegion" in $$parsedSource) {
+            $$parsedSource["PlayerRegion"] = $$createField4_0($$parsedSource["PlayerRegion"]);
+        }
+        if ("PlayerClub" in $$parsedSource) {
+            $$parsedSource["PlayerClub"] = $$createField5_0($$parsedSource["PlayerClub"]);
+        }
+        return new Player($$parsedSource as Partial<Player>);
+    }
+}
+
+/**
+ * Referee : Person details
+ */
+export class Referee {
+    /**
+     * More than 255 referees
+     */
+    "RefereeID": number;
+    "RefereeFirstname": string;
+    "RefereeLastname": string;
+    "RefereeNationID": number;
+    "RefereeRegionID": number;
+    "RefereeClubID": number;
+
+    /** Creates a new Referee instance. */
+    constructor($$source: Partial<Referee> = {}) {
+        if (!("RefereeID" in $$source)) {
+            this["RefereeID"] = 0;
+        }
+        if (!("RefereeFirstname" in $$source)) {
+            this["RefereeFirstname"] = "";
+        }
+        if (!("RefereeLastname" in $$source)) {
+            this["RefereeLastname"] = "";
+        }
+        if (!("RefereeNationID" in $$source)) {
+            this["RefereeNationID"] = 0;
+        }
+        if (!("RefereeRegionID" in $$source)) {
+            this["RefereeRegionID"] = 0;
+        }
+        if (!("RefereeClubID" in $$source)) {
+            this["RefereeClubID"] = 0;
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Referee instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Referee {
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        return new Referee($$parsedSource as Partial<Referee>);
+    }
+}
+
+export class Region {
+    "region_id": number;
+    "region_name": string;
+
+    /** Creates a new Region instance. */
+    constructor($$source: Partial<Region> = {}) {
+        if (!("region_id" in $$source)) {
+            this["region_id"] = 0;
+        }
+        if (!("region_name" in $$source)) {
+            this["region_name"] = "";
+        }
+
+        Object.assign(this, $$source);
+    }
+
+    /**
+     * Creates a new Region instance from a string or object.
+     */
+    static createFrom($$source: any = {}): Region {
+        let $$parsedSource = typeof $$source === 'string' ? JSON.parse($$source) : $$source;
+        return new Region($$parsedSource as Partial<Region>);
+    }
+}
+
+/**
+ * Stage : Stage details
+ */
+export type Stage = any;
+
+/**
+ * State : Competition state
+ */
+export enum State {
+    /**
+     * The Go zero value for the underlying type of the enum.
+     */
+    $zero = 0,
+
+    /**
+     * 0
+     */
+    REGISTERING = 0,
+
+    /**
+     * 1
+     */
+    STARTED = 1,
+
+    /**
+     * 2
+     */
+    FINISHED = 2,
+
+    /**
+     * 3
+     */
+    IDLE = 3,
+};
+
+/**
+ * Weapon : Weapon used in competition
+ */
+export enum Weapon {
+    /**
+     * The Go zero value for the underlying type of the enum.
+     */
+    $zero = 0,
+
+    /**
+     * 0
+     */
+    FOIL = 0,
+
+    /**
+     * 1
+     */
+    EPEE = 1,
+
+    /**
+     * 2
+     */
+    SABRE = 2,
+};
+
+// Private type creation functions
+const $$createType0 = $Create.Map($Create.Any, $Create.Any);
+const $$createType1 = Player.createFrom;
+const $$createType2 = $Create.Nullable($$createType1);
+const $$createType3 = $Create.Map($Create.Any, $$createType2);
+const $$createType4 = Nation.createFrom;
+const $$createType5 = $Create.Nullable($$createType4);
+const $$createType6 = Region.createFrom;
+const $$createType7 = $Create.Nullable($$createType6);
+const $$createType8 = Club.createFrom;
+const $$createType9 = $Create.Nullable($$createType8);
diff --git a/frontend/bindings/changeme/astro/services/player.ts b/frontend/bindings/changeme/astro/services/player.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f6a1447c21ad91ba5d246c852609badb27f59fcd
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/player.ts
@@ -0,0 +1,33 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+/**
+ * Player : Person details
+ * @module
+ */
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Call as $Call, Create as $Create} from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as $models from "./models.js";
+
+export function GenerateRandomPlayer(): Promise<$models.Player | null> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2771769734) as any;
+    let $typingPromise = $resultPromise.then(($result) => {
+        return $$createType1($result);
+    }) as any;
+    $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
+    return $typingPromise;
+}
+
+export function String(): Promise<string> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2659461938) as any;
+    return $resultPromise;
+}
+
+// Private type creation functions
+const $$createType0 = $models.Player.createFrom;
+const $$createType1 = $Create.Nullable($$createType0);
diff --git a/frontend/bindings/changeme/astro/services/pool.ts b/frontend/bindings/changeme/astro/services/pool.ts
new file mode 100644
index 0000000000000000000000000000000000000000..879a8ccc32d3966798bab032f619b11ed541c019
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/pool.ts
@@ -0,0 +1,35 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Call as $Call, Create as $Create} from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as $models from "./models.js";
+
+export function AddPlayer(player: $models.Player): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2419770436, player) as any;
+    return $resultPromise;
+}
+
+export function PlayerPosition(player: $models.Player): Promise<number> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(199697208, player) as any;
+    return $resultPromise;
+}
+
+export function RemovePlayer(player: $models.Player): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2585363663, player) as any;
+    return $resultPromise;
+}
+
+export function SetReferee(referee: $models.Referee): Promise<void> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(1520561734, referee) as any;
+    return $resultPromise;
+}
+
+export function String(): Promise<string> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2027138107) as any;
+    return $resultPromise;
+}
diff --git a/frontend/bindings/changeme/astro/services/session.ts b/frontend/bindings/changeme/astro/services/session.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b9b233d6f59afe9a67e40d47af1938f1759a9d27
--- /dev/null
+++ b/frontend/bindings/changeme/astro/services/session.ts
@@ -0,0 +1,75 @@
+// Cynhyrchwyd y ffeil hon yn awtomatig. PEIDIWCH Â MODIWL
+// This file is automatically generated. DO NOT EDIT
+
+/**
+ * Session : Session details
+ * @module
+ */
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import {Call as $Call, Create as $Create} from "@wailsio/runtime";
+
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore: Unused imports
+import * as $models from "./models.js";
+
+export function AddCompetition(name: string, category: string, weapon: string): Promise<void> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3450672978, name, category, weapon) as any;
+    return $resultPromise;
+}
+
+export function AddPlayerToCompetition(competitionID: number, player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(392649030, competitionID, player) as any;
+    return $resultPromise;
+}
+
+export function GetAllPlayersFromCompetition(competitionID: number): Promise<($models.Player | null)[]> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3547487506, competitionID) as any;
+    let $typingPromise = $resultPromise.then(($result) => {
+        return $$createType2($result);
+    }) as any;
+    $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
+    return $typingPromise;
+}
+
+export function GetCompetition(competitionID: number): Promise<$models.Competition | null> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3131533323, competitionID) as any;
+    let $typingPromise = $resultPromise.then(($result) => {
+        return $$createType4($result);
+    }) as any;
+    $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
+    return $typingPromise;
+}
+
+export function GetCompetitions(): Promise<$models.Competition[]> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(1300853992) as any;
+    let $typingPromise = $resultPromise.then(($result) => {
+        return $$createType5($result);
+    }) as any;
+    $typingPromise.cancel = $resultPromise.cancel.bind($resultPromise);
+    return $typingPromise;
+}
+
+export function RemoveCompetition(competitionID: number): Promise<void> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(2428225511, competitionID) as any;
+    return $resultPromise;
+}
+
+export function RemovePlayerFromCompetition(competitionID: number, player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(1688030656, competitionID, player) as any;
+    return $resultPromise;
+}
+
+export function UpdateCompetitionPlayer(competitionID: number, player: $models.Player | null): Promise<boolean> & { cancel(): void } {
+    let $resultPromise = $Call.ByID(3540307881, competitionID, player) as any;
+    return $resultPromise;
+}
+
+// Private type creation functions
+const $$createType0 = $models.Player.createFrom;
+const $$createType1 = $Create.Nullable($$createType0);
+const $$createType2 = $Create.Array($$createType1);
+const $$createType3 = $models.Competition.createFrom;
+const $$createType4 = $Create.Nullable($$createType3);
+const $$createType5 = $Create.Array($$createType3);