diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f1f409f..df524cc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -39,7 +39,7 @@ lint-data-manager:
- cd services/data-manager
- go mod download
- golangci-lint --version
- - golangci-lint run -v --skip-dirs=migrations --timeout=5m
+ - golangci-lint run -v --timeout=5m
rules:
- changes:
- services/data-manager/**/*
@@ -51,7 +51,7 @@ lint-ical:
- cd services/ical
- go mod download
- golangci-lint --version
- - golangci-lint run -v --skip-dirs=migrations --timeout=5m
+ - golangci-lint run -v --timeout=5m
rules:
- changes:
- services/ical/**/*
diff --git a/services/data-manager/migrations/1687801090_initial_superuser.go b/services/data-manager/migrations/1687801090_initial_superuser.go
new file mode 100644
index 0000000..5f8541c
--- /dev/null
+++ b/services/data-manager/migrations/1687801090_initial_superuser.go
@@ -0,0 +1,31 @@
+package migrations
+
+import (
+ "github.com/pocketbase/pocketbase/core"
+ m "github.com/pocketbase/pocketbase/migrations"
+)
+
+func init() {
+ m.Register(func(app core.App) error {
+ superusers, err := app.FindCollectionByNameOrId(core.CollectionNameSuperusers)
+ if err != nil {
+ return err
+ }
+
+ record := core.NewRecord(superusers)
+
+ // note: the values can be eventually loaded via os.Getenv(key)
+ // or from a special local config file
+ record.Set("email", "demo@htwkalender.de")
+ record.Set("password", "htwkalender-demo")
+
+ return app.Save(record)
+ }, func(app core.App) error { // optional revert operation
+ record, _ := app.FindAuthRecordByEmail(core.CollectionNameSuperusers, "demo@htwkalender.de")
+ if record == nil {
+ return nil // probably already deleted
+ }
+
+ return app.Delete(record)
+ })
+}
diff --git a/services/data-manager/migrations/1695150679_collections_snapshot.go b/services/data-manager/migrations/1695150679_collections_snapshot.go
deleted file mode 100644
index 4e2da1a..0000000
--- a/services/data-manager/migrations/1695150679_collections_snapshot.go
+++ /dev/null
@@ -1,399 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "_pb_users_auth_",
- "created": "2023-09-19 17:30:50.598Z",
- "updated": "2023-09-19 17:31:15.957Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "unique": false,
- "options": {
- "maxSelect": 1,
- "maxSize": 5242880,
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "requireEmail": false
- }
- },
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-09-19 17:31:15.957Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-09-19 17:31:15.957Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "unique": false,
- "options": {}
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2023-09-19 17:31:15.958Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "7vsr9h6p",
- "name": "Start",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "wwpokofe",
- "name": "End",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_orp1NWL` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Day` + "`" + `,\n ` + "`" + `Week` + "`" + `,\n ` + "`" + `Start` + "`" + `,\n ` + "`" + `End` + "`" + `,\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `Prof` + "`" + `,\n ` + "`" + `Rooms` + "`" + `,\n ` + "`" + `EventType` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- }
- ]`
-
- var collections []*models.Collection
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1695151278_add_admin_account.go b/services/data-manager/migrations/1695151278_add_admin_account.go
deleted file mode 100644
index f5cde04..0000000
--- a/services/data-manager/migrations/1695151278_add_admin_account.go
+++ /dev/null
@@ -1,50 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- admin := &models.Admin{}
- admin.Email = "demo@htwkalender.de"
- err := admin.SetPassword("htwkalender-demo")
- if err != nil {
- return err
- }
-
- return dao.SaveAdmin(admin)
- }, func(db dbx.Builder) error { // optional revert operation
-
- dao := daos.New(db)
-
- admin, _ := dao.FindAdminByEmail("test@example.com")
- if admin != nil {
- return dao.DeleteAdmin(admin)
- }
-
- // already deleted
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1697532023_collections_snapshot.go b/services/data-manager/migrations/1697532023_collections_snapshot.go
deleted file mode 100644
index de0e401..0000000
--- a/services/data-manager/migrations/1697532023_collections_snapshot.go
+++ /dev/null
@@ -1,400 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-09-19 17:31:15.957Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-10-17 08:37:17.943Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "unique": false,
- "options": {}
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2023-09-19 17:31:15.958Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "7vsr9h6p",
- "name": "Start",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "wwpokofe",
- "name": "End",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_orp1NWL` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Day` + "`" + `,\n ` + "`" + `Week` + "`" + `,\n ` + "`" + `Start` + "`" + `,\n ` + "`" + `End` + "`" + `,\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `Prof` + "`" + `,\n ` + "`" + `Rooms` + "`" + `,\n ` + "`" + `EventType` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "_pb_users_auth_",
- "created": "2023-10-08 16:32:34.131Z",
- "updated": "2023-10-08 16:32:34.315Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "unique": false,
- "options": {
- "maxSelect": 1,
- "maxSize": 5242880,
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "requireEmail": false
- }
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1697570688_collections_snapshot.go b/services/data-manager/migrations/1697570688_collections_snapshot.go
deleted file mode 100644
index bc8621d..0000000
--- a/services/data-manager/migrations/1697570688_collections_snapshot.go
+++ /dev/null
@@ -1,400 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-10-17 10:50:08.270Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-10-17 18:47:10.221Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "unique": false,
- "options": {}
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": "",
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2023-10-17 10:50:08.270Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "7vsr9h6p",
- "name": "Start",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "wwpokofe",
- "name": "End",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_orp1NWL` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Day` + "`" + `,\n ` + "`" + `Week` + "`" + `,\n ` + "`" + `Start` + "`" + `,\n ` + "`" + `End` + "`" + `,\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `Prof` + "`" + `,\n ` + "`" + `Rooms` + "`" + `,\n ` + "`" + `EventType` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "_pb_users_auth_",
- "created": "2023-09-22 09:31:11.498Z",
- "updated": "2023-10-17 10:50:08.270Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "unique": false,
- "options": {
- "maxSelect": 1,
- "maxSize": 5242880,
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "requireEmail": false
- }
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1698017941_updated_events.go b/services/data-manager/migrations/1698017941_updated_events.go
deleted file mode 100644
index 6756ccc..0000000
--- a/services/data-manager/migrations/1698017941_updated_events.go
+++ /dev/null
@@ -1,68 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models/schema"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- // add
- new_uuid := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "0kahthzr",
- "name": "uuid",
- "type": "text",
- "required": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }`), new_uuid)
- collection.Schema.AddField(new_uuid)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- // remove
- collection.Schema.RemoveField("0kahthzr")
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1698770845_updated_events.go b/services/data-manager/migrations/1698770845_updated_events.go
deleted file mode 100644
index 2b8fde5..0000000
--- a/services/data-manager/migrations/1698770845_updated_events.go
+++ /dev/null
@@ -1,157 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models/schema"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[]`), &collection.Indexes)
-
- // remove
- collection.Schema.RemoveField("7vsr9h6p")
-
- // remove
- collection.Schema.RemoveField("wwpokofe")
-
- // add
- new_start := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "6hkjwgb4",
- "name": "start",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }`), new_start)
- collection.Schema.AddField(new_start)
-
- // add
- new_end := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "szbefpjf",
- "name": "end",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }`), new_end)
- collection.Schema.AddField(new_end)
-
- // add
- new_Compulsory := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "nlnnxu7x",
- "name": "Compulsory",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }`), new_Compulsory)
- collection.Schema.AddField(new_Compulsory)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[
- "CREATE UNIQUE INDEX `+"`"+`idx_orp1NWL`+"`"+` ON `+"`"+`events`+"`"+` (\n `+"`"+`Day`+"`"+`,\n `+"`"+`Week`+"`"+`,\n `+"`"+`Start`+"`"+`,\n `+"`"+`End`+"`"+`,\n `+"`"+`Name`+"`"+`,\n `+"`"+`course`+"`"+`,\n `+"`"+`Prof`+"`"+`,\n `+"`"+`Rooms`+"`"+`,\n `+"`"+`EventType`+"`"+`\n)"
- ]`), &collection.Indexes)
-
- // add
- del_Start := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "7vsr9h6p",
- "name": "Start",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }`), del_Start)
- collection.Schema.AddField(del_Start)
-
- // add
- del_End := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "wwpokofe",
- "name": "End",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }`), del_End)
- collection.Schema.AddField(del_End)
-
- // remove
- collection.Schema.RemoveField("6hkjwgb4")
-
- // remove
- collection.Schema.RemoveField("szbefpjf")
-
- // remove
- collection.Schema.RemoveField("nlnnxu7x")
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1698770863_updated_events.go b/services/data-manager/migrations/1698770863_updated_events.go
deleted file mode 100644
index fd2f613..0000000
--- a/services/data-manager/migrations/1698770863_updated_events.go
+++ /dev/null
@@ -1,53 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[
- "CREATE INDEX `+"`"+`idx_4vOTAiC`+"`"+` ON `+"`"+`events`+"`"+` (\n `+"`"+`Name`+"`"+`,\n `+"`"+`course`+"`"+`,\n `+"`"+`start`+"`"+`,\n `+"`"+`end`+"`"+`,\n `+"`"+`semester`+"`"+`,\n `+"`"+`EventType`+"`"+`,\n `+"`"+`Compulsory`+"`"+`\n)"
- ]`), &collection.Indexes)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("7her4515qsmrxe8")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[]`), &collection.Indexes)
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1698770891_collections_snapshot.go b/services/data-manager/migrations/1698770891_collections_snapshot.go
deleted file mode 100644
index feb273a..0000000
--- a/services/data-manager/migrations/1698770891_collections_snapshot.go
+++ /dev/null
@@ -1,447 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "_pb_users_auth_",
- "created": "2023-09-20 10:23:59.315Z",
- "updated": "2023-10-17 22:18:39.192Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "maxSelect": 1,
- "maxSize": 5242880,
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "requireEmail": false
- }
- },
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-21 16:53:51.811Z",
- "updated": "2023-10-17 22:18:39.190Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-21 16:53:51.812Z",
- "updated": "2023-10-17 22:18:39.191Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {}
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": "",
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-28 12:07:17.340Z",
- "updated": "2023-10-31 16:47:43.090Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "0kahthzr",
- "name": "uuid",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "6hkjwgb4",
- "name": "start",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "szbefpjf",
- "name": "end",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "nlnnxu7x",
- "name": "Compulsory",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE INDEX ` + "`" + `idx_4vOTAiC` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `start` + "`" + `,\n ` + "`" + `end` + "`" + `,\n ` + "`" + `semester` + "`" + `,\n ` + "`" + `EventType` + "`" + `,\n ` + "`" + `Compulsory` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1700512738_updated_feeds.go b/services/data-manager/migrations/1700512738_updated_feeds.go
deleted file mode 100644
index 0a1bc52..0000000
--- a/services/data-manager/migrations/1700512738_updated_feeds.go
+++ /dev/null
@@ -1,68 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models/schema"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("d65h4wh7zk13gxp")
- if err != nil {
- return err
- }
-
- // add
- new_retrieved := &schema.SchemaField{}
- json.Unmarshal([]byte(`{
- "system": false,
- "id": "wmmney8x",
- "name": "retrieved",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }`), new_retrieved)
- collection.Schema.AddField(new_retrieved)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("d65h4wh7zk13gxp")
- if err != nil {
- return err
- }
-
- // remove
- collection.Schema.RemoveField("wmmney8x")
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1700512916_collections_snapshot.go b/services/data-manager/migrations/1700512916_collections_snapshot.go
deleted file mode 100644
index deb0aaa..0000000
--- a/services/data-manager/migrations/1700512916_collections_snapshot.go
+++ /dev/null
@@ -1,460 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-11-01 21:17:43.567Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2023-11-20 20:38:58.258Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {}
- },
- {
- "system": false,
- "id": "wmmney8x",
- "name": "retrieved",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": "",
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2023-11-01 21:17:43.567Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "0kahthzr",
- "name": "uuid",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "6hkjwgb4",
- "name": "start",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "szbefpjf",
- "name": "end",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "nlnnxu7x",
- "name": "Compulsory",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE INDEX ` + "`" + `idx_4vOTAiC` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `start` + "`" + `,\n ` + "`" + `end` + "`" + `,\n ` + "`" + `semester` + "`" + `,\n ` + "`" + `EventType` + "`" + `,\n ` + "`" + `Compulsory` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "_pb_users_auth_",
- "created": "2023-11-01 21:17:43.390Z",
- "updated": "2023-11-01 21:17:43.567Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "maxSelect": 1,
- "maxSize": 5242880,
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "requireEmail": false
- }
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1706827339_collections_snapshot.go b/services/data-manager/migrations/1706827339_collections_snapshot.go
deleted file mode 100644
index 62b66f8..0000000
--- a/services/data-manager/migrations/1706827339_collections_snapshot.go
+++ /dev/null
@@ -1,477 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2024-02-01 22:35:50.512Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "min": 2,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "bdhcrksy",
- "name": "semester",
- "type": "text",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "min": 2,
- "max": 2,
- "pattern": "ws|ss"
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (` + "`" + `course` + "`" + `)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2024-02-01 13:34:43.834Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "maxSize": 2000000
- }
- },
- {
- "system": false,
- "id": "wmmney8x",
- "name": "retrieved",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": "",
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2024-02-01 13:34:43.833Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "0kahthzr",
- "name": "uuid",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "6hkjwgb4",
- "name": "start",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "szbefpjf",
- "name": "end",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "nlnnxu7x",
- "name": "Compulsory",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE INDEX ` + "`" + `idx_4vOTAiC` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `start` + "`" + `,\n ` + "`" + `end` + "`" + `,\n ` + "`" + `semester` + "`" + `,\n ` + "`" + `EventType` + "`" + `,\n ` + "`" + `Compulsory` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "_pb_users_auth_",
- "created": "2024-02-01 13:34:43.663Z",
- "updated": "2024-02-01 13:34:43.833Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "maxSelect": 1,
- "maxSize": 5242880,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "onlyVerified": false,
- "requireEmail": false
- }
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1706827586_updated_groups.go b/services/data-manager/migrations/1706827586_updated_groups.go
deleted file mode 100644
index 643ba94..0000000
--- a/services/data-manager/migrations/1706827586_updated_groups.go
+++ /dev/null
@@ -1,55 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("cfq9mqlmd97v8z5")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[
- "CREATE UNIQUE INDEX `+"`"+`idx_rcaN2Oq`+"`"+` ON `+"`"+`groups`+"`"+` (\n `+"`"+`course`+"`"+`,\n `+"`"+`semester`+"`"+`\n)"
- ]`), &collection.Indexes)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("cfq9mqlmd97v8z5")
- if err != nil {
- return err
- }
-
- json.Unmarshal([]byte(`[
- "CREATE UNIQUE INDEX `+"`"+`idx_rcaN2Oq`+"`"+` ON `+"`"+`groups`+"`"+` (`+"`"+`course`+"`"+`)"
- ]`), &collection.Indexes)
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1720871249_collections_snapshot.go b/services/data-manager/migrations/1720871249_collections_snapshot.go
deleted file mode 100644
index 4075f65..0000000
--- a/services/data-manager/migrations/1720871249_collections_snapshot.go
+++ /dev/null
@@ -1,461 +0,0 @@
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- jsonData := `[
- {
- "id": "cfq9mqlmd97v8z5",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2024-07-13 11:37:49.151Z",
- "name": "groups",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "85msl21p",
- "name": "university",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "2sii4dtp",
- "name": "shortcut",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "uiwgo28f",
- "name": "groupId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "y0l1lrzs",
- "name": "course",
- "type": "text",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "min": 2,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "kr62mhbz",
- "name": "faculty",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "ya6znpez",
- "name": "facultyId",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "bdhcrksy",
- "name": "semester",
- "type": "text",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "min": 2,
- "max": 2,
- "pattern": "ws|ss"
- }
- }
- ],
- "indexes": [
- "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (\n ` + "`" + `course` + "`" + `,\n ` + "`" + `semester` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "d65h4wh7zk13gxp",
- "created": "2023-09-19 17:31:15.957Z",
- "updated": "2024-07-13 11:37:49.145Z",
- "name": "feeds",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "cowxjfmc",
- "name": "modules",
- "type": "json",
- "required": true,
- "presentable": false,
- "unique": false,
- "options": {
- "maxSize": 2000000
- }
- },
- {
- "system": false,
- "id": "wmmney8x",
- "name": "retrieved",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- }
- ],
- "indexes": [],
- "listRule": null,
- "viewRule": "",
- "createRule": null,
- "updateRule": "",
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "7her4515qsmrxe8",
- "created": "2023-09-19 17:31:15.958Z",
- "updated": "2024-07-13 11:37:49.145Z",
- "name": "events",
- "type": "base",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "m8ne8e3m",
- "name": "Day",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "xnsxqp7j",
- "name": "Week",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "aeuskrjo",
- "name": "Name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "klrzqyw0",
- "name": "EventType",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "5zltexoy",
- "name": "Prof",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "gy3nvfmx",
- "name": "Rooms",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "hn7b8dfy",
- "name": "Notes",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "axskpwm8",
- "name": "BookedAt",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vyyefxp7",
- "name": "course",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "vlbpm9fz",
- "name": "semester",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "0kahthzr",
- "name": "uuid",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "6hkjwgb4",
- "name": "start",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "szbefpjf",
- "name": "end",
- "type": "date",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": "",
- "max": ""
- }
- },
- {
- "system": false,
- "id": "nlnnxu7x",
- "name": "Compulsory",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- }
- ],
- "indexes": [
- "CREATE INDEX ` + "`" + `idx_4vOTAiC` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `start` + "`" + `,\n ` + "`" + `end` + "`" + `,\n ` + "`" + `semester` + "`" + `,\n ` + "`" + `EventType` + "`" + `,\n ` + "`" + `Compulsory` + "`" + `\n)"
- ],
- "listRule": null,
- "viewRule": null,
- "createRule": null,
- "updateRule": null,
- "deleteRule": null,
- "options": {}
- },
- {
- "id": "_pb_users_auth_",
- "created": "2024-07-13 11:37:48.913Z",
- "updated": "2024-07-13 11:37:49.145Z",
- "name": "users",
- "type": "auth",
- "system": false,
- "schema": [
- {
- "system": false,
- "id": "users_name",
- "name": "name",
- "type": "text",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "min": null,
- "max": null,
- "pattern": ""
- }
- },
- {
- "system": false,
- "id": "users_avatar",
- "name": "avatar",
- "type": "file",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {
- "mimeTypes": [
- "image/jpeg",
- "image/png",
- "image/svg+xml",
- "image/gif",
- "image/webp"
- ],
- "thumbs": null,
- "maxSelect": 1,
- "maxSize": 5242880,
- "protected": false
- }
- }
- ],
- "indexes": [],
- "listRule": "id = @request.auth.id",
- "viewRule": "id = @request.auth.id",
- "createRule": "",
- "updateRule": "id = @request.auth.id",
- "deleteRule": "id = @request.auth.id",
- "options": {
- "allowEmailAuth": true,
- "allowOAuth2Auth": true,
- "allowUsernameAuth": true,
- "exceptEmailDomains": null,
- "manageRule": null,
- "minPasswordLength": 8,
- "onlyEmailDomains": null,
- "onlyVerified": false,
- "requireEmail": false
- }
- }
- ]`
-
- collections := []*models.Collection{}
- if err := json.Unmarshal([]byte(jsonData), &collections); err != nil {
- return err
- }
-
- return daos.New(db).ImportCollections(collections, true, nil)
- }, func(db dbx.Builder) error {
- return nil
- })
-}
diff --git a/services/data-manager/migrations/1720871405_updated_feeds.go b/services/data-manager/migrations/1720871405_updated_feeds.go
deleted file mode 100644
index 1a9e561..0000000
--- a/services/data-manager/migrations/1720871405_updated_feeds.go
+++ /dev/null
@@ -1,51 +0,0 @@
-package migrations
-
-import (
- "encoding/json"
-
- "github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase/daos"
- m "github.com/pocketbase/pocketbase/migrations"
- "github.com/pocketbase/pocketbase/models/schema"
-)
-
-func init() {
- m.Register(func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("d65h4wh7zk13gxp")
- if err != nil {
- return err
- }
-
- // add
- new_deleted := &schema.SchemaField{}
- if err := json.Unmarshal([]byte(`{
- "system": false,
- "id": "5d7vjjgo",
- "name": "deleted",
- "type": "bool",
- "required": false,
- "presentable": false,
- "unique": false,
- "options": {}
- }`), new_deleted); err != nil {
- return err
- }
- collection.Schema.AddField(new_deleted)
-
- return dao.SaveCollection(collection)
- }, func(db dbx.Builder) error {
- dao := daos.New(db)
-
- collection, err := dao.FindCollectionByNameOrId("d65h4wh7zk13gxp")
- if err != nil {
- return err
- }
-
- // remove
- collection.Schema.RemoveField("5d7vjjgo")
-
- return dao.SaveCollection(collection)
- })
-}
diff --git a/services/data-manager/migrations/1745249435_collections_snapshot.go b/services/data-manager/migrations/1745249435_collections_snapshot.go
new file mode 100644
index 0000000..1b8214e
--- /dev/null
+++ b/services/data-manager/migrations/1745249435_collections_snapshot.go
@@ -0,0 +1,1273 @@
+package migrations
+
+import (
+ "github.com/pocketbase/pocketbase/core"
+ m "github.com/pocketbase/pocketbase/migrations"
+)
+
+func init() {
+ m.Register(func(app core.App) error {
+ jsonData := `[
+ {
+ "createRule": null,
+ "deleteRule": null,
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "85msl21p",
+ "max": 0,
+ "min": 0,
+ "name": "university",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "2sii4dtp",
+ "max": 0,
+ "min": 0,
+ "name": "shortcut",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "uiwgo28f",
+ "max": 0,
+ "min": 0,
+ "name": "groupId",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "y0l1lrzs",
+ "max": 0,
+ "min": 2,
+ "name": "course",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "kr62mhbz",
+ "max": 0,
+ "min": 0,
+ "name": "faculty",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "ya6znpez",
+ "max": 0,
+ "min": 0,
+ "name": "facultyId",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "bdhcrksy",
+ "max": 2,
+ "min": 2,
+ "name": "semester",
+ "pattern": "ws|ss",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ }
+ ],
+ "id": "cfq9mqlmd97v8z5",
+ "indexes": [
+ "CREATE UNIQUE INDEX ` + "`" + `idx_rcaN2Oq` + "`" + ` ON ` + "`" + `groups` + "`" + ` (\n ` + "`" + `course` + "`" + `,\n ` + "`" + `semester` + "`" + `\n)"
+ ],
+ "listRule": null,
+ "name": "groups",
+ "system": false,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": null
+ },
+ {
+ "createRule": null,
+ "deleteRule": null,
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "cowxjfmc",
+ "maxSize": 2000000,
+ "name": "modules",
+ "presentable": false,
+ "required": true,
+ "system": false,
+ "type": "json"
+ },
+ {
+ "hidden": false,
+ "id": "wmmney8x",
+ "max": "",
+ "min": "",
+ "name": "retrieved",
+ "presentable": false,
+ "required": false,
+ "system": false,
+ "type": "date"
+ },
+ {
+ "hidden": false,
+ "id": "5d7vjjgo",
+ "name": "deleted",
+ "presentable": false,
+ "required": false,
+ "system": false,
+ "type": "bool"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ }
+ ],
+ "id": "d65h4wh7zk13gxp",
+ "indexes": [],
+ "listRule": null,
+ "name": "feeds",
+ "system": false,
+ "type": "base",
+ "updateRule": "",
+ "viewRule": ""
+ },
+ {
+ "createRule": null,
+ "deleteRule": null,
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "m8ne8e3m",
+ "max": 0,
+ "min": 0,
+ "name": "Day",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "xnsxqp7j",
+ "max": 0,
+ "min": 0,
+ "name": "Week",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "aeuskrjo",
+ "max": 0,
+ "min": 0,
+ "name": "Name",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "klrzqyw0",
+ "max": 0,
+ "min": 0,
+ "name": "EventType",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "5zltexoy",
+ "max": 0,
+ "min": 0,
+ "name": "Prof",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "gy3nvfmx",
+ "max": 0,
+ "min": 0,
+ "name": "Rooms",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "hn7b8dfy",
+ "max": 0,
+ "min": 0,
+ "name": "Notes",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "axskpwm8",
+ "max": 0,
+ "min": 0,
+ "name": "BookedAt",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "vyyefxp7",
+ "max": 0,
+ "min": 0,
+ "name": "course",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "vlbpm9fz",
+ "max": 0,
+ "min": 0,
+ "name": "semester",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "0kahthzr",
+ "max": 0,
+ "min": 0,
+ "name": "uuid",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "6hkjwgb4",
+ "max": "",
+ "min": "",
+ "name": "start",
+ "presentable": false,
+ "required": false,
+ "system": false,
+ "type": "date"
+ },
+ {
+ "hidden": false,
+ "id": "szbefpjf",
+ "max": "",
+ "min": "",
+ "name": "end",
+ "presentable": false,
+ "required": false,
+ "system": false,
+ "type": "date"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "nlnnxu7x",
+ "max": 0,
+ "min": 0,
+ "name": "Compulsory",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ }
+ ],
+ "id": "7her4515qsmrxe8",
+ "indexes": [
+ "CREATE INDEX ` + "`" + `idx_4vOTAiC` + "`" + ` ON ` + "`" + `events` + "`" + ` (\n ` + "`" + `Name` + "`" + `,\n ` + "`" + `course` + "`" + `,\n ` + "`" + `start` + "`" + `,\n ` + "`" + `end` + "`" + `,\n ` + "`" + `semester` + "`" + `,\n ` + "`" + `EventType` + "`" + `,\n ` + "`" + `Compulsory` + "`" + `\n)"
+ ],
+ "listRule": null,
+ "name": "events",
+ "system": false,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": null
+ },
+ {
+ "authAlert": {
+ "emailTemplate": {
+ "body": "
Hello,
\nWe noticed a login to your {APP_NAME} account from a new location.
\nIf this was you, you may disregard this email.
\nIf this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Login from a new location"
+ },
+ "enabled": true
+ },
+ "authRule": "",
+ "authToken": {
+ "duration": 1209600
+ },
+ "confirmEmailChangeTemplate": {
+ "body": "Hello,
\nClick on the button below to confirm your new email address.
\n\n Confirm new email\n
\nIf you didn't ask to change your email address, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Confirm your {APP_NAME} new email address"
+ },
+ "createRule": "",
+ "deleteRule": "id = @request.auth.id",
+ "emailChangeToken": {
+ "duration": 1800
+ },
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "cost": 10,
+ "hidden": true,
+ "id": "password901924565",
+ "max": 0,
+ "min": 8,
+ "name": "password",
+ "pattern": "",
+ "presentable": false,
+ "required": true,
+ "system": true,
+ "type": "password"
+ },
+ {
+ "autogeneratePattern": "[a-zA-Z0-9_]{50}",
+ "hidden": true,
+ "id": "text2504183744",
+ "max": 60,
+ "min": 30,
+ "name": "tokenKey",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "exceptDomains": null,
+ "hidden": false,
+ "id": "email3885137012",
+ "name": "email",
+ "onlyDomains": null,
+ "presentable": false,
+ "required": false,
+ "system": true,
+ "type": "email"
+ },
+ {
+ "hidden": false,
+ "id": "bool1547992806",
+ "name": "emailVisibility",
+ "presentable": false,
+ "required": false,
+ "system": true,
+ "type": "bool"
+ },
+ {
+ "hidden": false,
+ "id": "bool256245529",
+ "name": "verified",
+ "presentable": false,
+ "required": false,
+ "system": true,
+ "type": "bool"
+ },
+ {
+ "autogeneratePattern": "users[0-9]{6}",
+ "hidden": false,
+ "id": "text4166911607",
+ "max": 150,
+ "min": 3,
+ "name": "username",
+ "pattern": "^[\\w][\\w\\.\\-]*$",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "users_name",
+ "max": 0,
+ "min": 0,
+ "name": "name",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": false,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "users_avatar",
+ "maxSelect": 1,
+ "maxSize": 5242880,
+ "mimeTypes": [
+ "image/jpeg",
+ "image/png",
+ "image/svg+xml",
+ "image/gif",
+ "image/webp"
+ ],
+ "name": "avatar",
+ "presentable": false,
+ "protected": false,
+ "required": false,
+ "system": false,
+ "thumbs": null,
+ "type": "file"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": false,
+ "type": "autodate"
+ }
+ ],
+ "fileToken": {
+ "duration": 120
+ },
+ "id": "_pb_users_auth_",
+ "indexes": [
+ "CREATE UNIQUE INDEX ` + "`" + `__pb_users_auth__username_idx` + "`" + ` ON ` + "`" + `users` + "`" + ` (username COLLATE NOCASE)",
+ "CREATE UNIQUE INDEX ` + "`" + `__pb_users_auth__email_idx` + "`" + ` ON ` + "`" + `users` + "`" + ` (` + "`" + `email` + "`" + `) WHERE ` + "`" + `email` + "`" + ` != ''",
+ "CREATE UNIQUE INDEX ` + "`" + `__pb_users_auth__tokenKey_idx` + "`" + ` ON ` + "`" + `users` + "`" + ` (` + "`" + `tokenKey` + "`" + `)"
+ ],
+ "listRule": "id = @request.auth.id",
+ "manageRule": null,
+ "mfa": {
+ "duration": 1800,
+ "enabled": false,
+ "rule": ""
+ },
+ "name": "users",
+ "oauth2": {
+ "enabled": false,
+ "mappedFields": {
+ "avatarURL": "",
+ "id": "",
+ "name": "",
+ "username": "username"
+ }
+ },
+ "otp": {
+ "duration": 180,
+ "emailTemplate": {
+ "body": "Hello,
\nYour one-time password is: {OTP}
\nIf you didn't ask for the one-time password, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "OTP for {APP_NAME}"
+ },
+ "enabled": false,
+ "length": 8
+ },
+ "passwordAuth": {
+ "enabled": true,
+ "identityFields": [
+ "email",
+ "username"
+ ]
+ },
+ "passwordResetToken": {
+ "duration": 1800
+ },
+ "resetPasswordTemplate": {
+ "body": "Hello,
\nClick on the button below to reset your password.
\n\n Reset password\n
\nIf you didn't ask to reset your password, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Reset your {APP_NAME} password"
+ },
+ "system": false,
+ "type": "auth",
+ "updateRule": "id = @request.auth.id",
+ "verificationTemplate": {
+ "body": "Hello,
\nThank you for joining us at {APP_NAME}.
\nClick on the button below to verify your email address.
\n\n Verify\n
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Verify your {APP_NAME} email"
+ },
+ "verificationToken": {
+ "duration": 604800
+ },
+ "viewRule": "id = @request.auth.id"
+ },
+ {
+ "authAlert": {
+ "emailTemplate": {
+ "body": "Hello,
\nWe noticed a login to your {APP_NAME} account from a new location.
\nIf this was you, you may disregard this email.
\nIf this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Login from a new location"
+ },
+ "enabled": true
+ },
+ "authRule": "",
+ "authToken": {
+ "duration": 1209600
+ },
+ "confirmEmailChangeTemplate": {
+ "body": "Hello,
\nClick on the button below to confirm your new email address.
\n\n Confirm new email\n
\nIf you didn't ask to change your email address, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Confirm your {APP_NAME} new email address"
+ },
+ "createRule": null,
+ "deleteRule": null,
+ "emailChangeToken": {
+ "duration": 1800
+ },
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "cost": 0,
+ "hidden": true,
+ "id": "password901924565",
+ "max": 0,
+ "min": 8,
+ "name": "password",
+ "pattern": "",
+ "presentable": false,
+ "required": true,
+ "system": true,
+ "type": "password"
+ },
+ {
+ "autogeneratePattern": "[a-zA-Z0-9]{50}",
+ "hidden": true,
+ "id": "text2504183744",
+ "max": 60,
+ "min": 30,
+ "name": "tokenKey",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "exceptDomains": null,
+ "hidden": false,
+ "id": "email3885137012",
+ "name": "email",
+ "onlyDomains": null,
+ "presentable": false,
+ "required": true,
+ "system": true,
+ "type": "email"
+ },
+ {
+ "hidden": false,
+ "id": "bool1547992806",
+ "name": "emailVisibility",
+ "presentable": false,
+ "required": false,
+ "system": true,
+ "type": "bool"
+ },
+ {
+ "hidden": false,
+ "id": "bool256245529",
+ "name": "verified",
+ "presentable": false,
+ "required": false,
+ "system": true,
+ "type": "bool"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ }
+ ],
+ "fileToken": {
+ "duration": 120
+ },
+ "id": "pbc_3142635823",
+ "indexes": [
+ "CREATE UNIQUE INDEX ` + "`" + `idx_tokenKey_pbc_3142635823` + "`" + ` ON ` + "`" + `_superusers` + "`" + ` (` + "`" + `tokenKey` + "`" + `)",
+ "CREATE UNIQUE INDEX ` + "`" + `idx_email_pbc_3142635823` + "`" + ` ON ` + "`" + `_superusers` + "`" + ` (` + "`" + `email` + "`" + `) WHERE ` + "`" + `email` + "`" + ` != ''"
+ ],
+ "listRule": null,
+ "manageRule": null,
+ "mfa": {
+ "duration": 1800,
+ "enabled": false,
+ "rule": ""
+ },
+ "name": "_superusers",
+ "oauth2": {
+ "enabled": false,
+ "mappedFields": {
+ "avatarURL": "",
+ "id": "",
+ "name": "",
+ "username": ""
+ }
+ },
+ "otp": {
+ "duration": 180,
+ "emailTemplate": {
+ "body": "Hello,
\nYour one-time password is: {OTP}
\nIf you didn't ask for the one-time password, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "OTP for {APP_NAME}"
+ },
+ "enabled": false,
+ "length": 8
+ },
+ "passwordAuth": {
+ "enabled": true,
+ "identityFields": [
+ "email"
+ ]
+ },
+ "passwordResetToken": {
+ "duration": 1800
+ },
+ "resetPasswordTemplate": {
+ "body": "Hello,
\nClick on the button below to reset your password.
\n\n Reset password\n
\nIf you didn't ask to reset your password, you can ignore this email.
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Reset your {APP_NAME} password"
+ },
+ "system": true,
+ "type": "auth",
+ "updateRule": null,
+ "verificationTemplate": {
+ "body": "Hello,
\nThank you for joining us at {APP_NAME}.
\nClick on the button below to verify your email address.
\n\n Verify\n
\n\n Thanks,
\n {APP_NAME} team\n
",
+ "subject": "Verify your {APP_NAME} email"
+ },
+ "verificationToken": {
+ "duration": 259200
+ },
+ "viewRule": null
+ },
+ {
+ "createRule": null,
+ "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text455797646",
+ "max": 0,
+ "min": 0,
+ "name": "collectionRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text127846527",
+ "max": 0,
+ "min": 0,
+ "name": "recordRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text2462348188",
+ "max": 0,
+ "min": 0,
+ "name": "provider",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text1044722854",
+ "max": 0,
+ "min": 0,
+ "name": "providerId",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ }
+ ],
+ "id": "pbc_2281828961",
+ "indexes": [
+ "CREATE UNIQUE INDEX ` + "`" + `idx_externalAuths_record_provider` + "`" + ` ON ` + "`" + `_externalAuths` + "`" + ` (collectionRef, recordRef, provider)",
+ "CREATE UNIQUE INDEX ` + "`" + `idx_externalAuths_collection_provider` + "`" + ` ON ` + "`" + `_externalAuths` + "`" + ` (collectionRef, provider, providerId)"
+ ],
+ "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "name": "_externalAuths",
+ "system": true,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
+ },
+ {
+ "createRule": null,
+ "deleteRule": null,
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text455797646",
+ "max": 0,
+ "min": 0,
+ "name": "collectionRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text127846527",
+ "max": 0,
+ "min": 0,
+ "name": "recordRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text1582905952",
+ "max": 0,
+ "min": 0,
+ "name": "method",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ }
+ ],
+ "id": "pbc_2279338944",
+ "indexes": [
+ "CREATE INDEX ` + "`" + `idx_mfas_collectionRef_recordRef` + "`" + ` ON ` + "`" + `_mfas` + "`" + ` (collectionRef,recordRef)"
+ ],
+ "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "name": "_mfas",
+ "system": true,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
+ },
+ {
+ "createRule": null,
+ "deleteRule": null,
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text455797646",
+ "max": 0,
+ "min": 0,
+ "name": "collectionRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text127846527",
+ "max": 0,
+ "min": 0,
+ "name": "recordRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "cost": 8,
+ "hidden": true,
+ "id": "password901924565",
+ "max": 0,
+ "min": 0,
+ "name": "password",
+ "pattern": "",
+ "presentable": false,
+ "required": true,
+ "system": true,
+ "type": "password"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": true,
+ "id": "text3866985172",
+ "max": 0,
+ "min": 0,
+ "name": "sentTo",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": false,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ }
+ ],
+ "id": "pbc_1638494021",
+ "indexes": [
+ "CREATE INDEX ` + "`" + `idx_otps_collectionRef_recordRef` + "`" + ` ON ` + "`" + `_otps` + "`" + ` (collectionRef, recordRef)"
+ ],
+ "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "name": "_otps",
+ "system": true,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
+ },
+ {
+ "createRule": null,
+ "deleteRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "fields": [
+ {
+ "autogeneratePattern": "[a-z0-9]{15}",
+ "hidden": false,
+ "id": "text3208210256",
+ "max": 15,
+ "min": 15,
+ "name": "id",
+ "pattern": "^[a-z0-9]+$",
+ "presentable": false,
+ "primaryKey": true,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text455797646",
+ "max": 0,
+ "min": 0,
+ "name": "collectionRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text127846527",
+ "max": 0,
+ "min": 0,
+ "name": "recordRef",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "autogeneratePattern": "",
+ "hidden": false,
+ "id": "text4228609354",
+ "max": 0,
+ "min": 0,
+ "name": "fingerprint",
+ "pattern": "",
+ "presentable": false,
+ "primaryKey": false,
+ "required": true,
+ "system": true,
+ "type": "text"
+ },
+ {
+ "hidden": false,
+ "id": "autodate2990389176",
+ "name": "created",
+ "onCreate": true,
+ "onUpdate": false,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ },
+ {
+ "hidden": false,
+ "id": "autodate3332085495",
+ "name": "updated",
+ "onCreate": true,
+ "onUpdate": true,
+ "presentable": false,
+ "system": true,
+ "type": "autodate"
+ }
+ ],
+ "id": "pbc_4275539003",
+ "indexes": [
+ "CREATE UNIQUE INDEX ` + "`" + `idx_authOrigins_unique_pairs` + "`" + ` ON ` + "`" + `_authOrigins` + "`" + ` (collectionRef, recordRef, fingerprint)"
+ ],
+ "listRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId",
+ "name": "_authOrigins",
+ "system": true,
+ "type": "base",
+ "updateRule": null,
+ "viewRule": "@request.auth.id != '' && recordRef = @request.auth.id && collectionRef = @request.auth.collectionId"
+ }
+ ]`
+
+ return app.ImportCollectionsByMarshaledJSON([]byte(jsonData), false)
+ }, func(app core.App) error {
+ return nil
+ })
+}
diff --git a/services/data-manager/model/eventModel.go b/services/data-manager/model/eventModel.go
index 7b9bf1b..faa4e82 100644
--- a/services/data-manager/model/eventModel.go
+++ b/services/data-manager/model/eventModel.go
@@ -17,11 +17,10 @@
package model
import (
+ "github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tools/types"
"slices"
"strings"
-
- "github.com/pocketbase/pocketbase/models"
- "github.com/pocketbase/pocketbase/tools/types"
)
type Events []Event
@@ -56,7 +55,7 @@ type Event struct {
BookedAt string `db:"BookedAt" json:"bookedAt"`
Course string `db:"course" json:"course"`
Semester string `db:"semester" json:"semester"`
- models.BaseModel
+ core.BaseModel
}
type EventType struct {
diff --git a/services/data-manager/model/eventModel_test.go b/services/data-manager/model/eventModel_test.go
index f1ca8d0..a5b4577 100644
--- a/services/data-manager/model/eventModel_test.go
+++ b/services/data-manager/model/eventModel_test.go
@@ -20,7 +20,7 @@ import (
"reflect"
"testing"
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/types"
)
@@ -87,7 +87,7 @@ func TestEventEquals(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
event Event
@@ -164,7 +164,7 @@ func TestEventAnonymizeEvent(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
@@ -234,7 +234,7 @@ func TestEventGetName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
@@ -294,7 +294,7 @@ func TestEventSetCourse(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
course string
@@ -354,7 +354,7 @@ func TestEventSetName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
name string
@@ -414,7 +414,7 @@ func TestEventTableName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
diff --git a/services/data-manager/model/feedModel.go b/services/data-manager/model/feedModel.go
index 106d38e..88d8979 100644
--- a/services/data-manager/model/feedModel.go
+++ b/services/data-manager/model/feedModel.go
@@ -17,15 +17,17 @@
package model
import (
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/types"
)
type Feed struct {
Modules string `db:"modules" json:"modules"`
Retrieved types.DateTime `db:"retrieved" json:"retrieved"`
+ Created types.DateTime `db:"created" json:"created"`
+ Updated types.DateTime `db:"updated" json:"updated"`
Deleted bool `db:"deleted" json:"deleted"`
- models.BaseModel
+ core.BaseModel
}
func (f *Feed) TableName() string {
diff --git a/services/data-manager/model/feedModel_test.go b/services/data-manager/model/feedModel_test.go
index f2de61b..ed15be7 100644
--- a/services/data-manager/model/feedModel_test.go
+++ b/services/data-manager/model/feedModel_test.go
@@ -1,7 +1,7 @@
package model
import (
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/types"
"testing"
)
@@ -10,7 +10,7 @@ func TestFeedSetModules(t *testing.T) {
type fields struct {
Modules string
Retrieved types.DateTime
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
modules string
@@ -25,7 +25,7 @@ func TestFeedSetModules(t *testing.T) {
fields: fields{
Modules: "",
Retrieved: types.DateTime{},
- BaseModel: models.BaseModel{},
+ BaseModel: core.BaseModel{},
},
args: args{
modules: "modules",
diff --git a/services/data-manager/model/seminarGroup.go b/services/data-manager/model/seminarGroup.go
index cff3235..5d514f3 100644
--- a/services/data-manager/model/seminarGroup.go
+++ b/services/data-manager/model/seminarGroup.go
@@ -26,3 +26,9 @@ type SeminarGroup struct {
Semester string
Events []Event
}
+
+type SeminarGroups []SeminarGroup
+
+func (group *SeminarGroup) UniqueKey() string {
+ return group.Course + group.Semester
+}
diff --git a/services/data-manager/service/addCalDavRoutes.go b/services/data-manager/service/addCalDavRoutes.go
index 18271f2..d14e42a 100644
--- a/services/data-manager/service/addCalDavRoutes.go
+++ b/services/data-manager/service/addCalDavRoutes.go
@@ -17,62 +17,39 @@
package service
import (
- "github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase"
- "github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
+ "htwkalender/data-manager/model"
"htwkalender/data-manager/service/feed"
"htwkalender/data-manager/service/ical"
- "io"
"log/slog"
"net/http"
)
-func addFeedRoutes(app *pocketbase.PocketBase) {
- app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodPost,
- Path: "/api/feed",
- Handler: func(c echo.Context) error {
- requestBody, _ := io.ReadAll(c.Request().Body)
- result, err := ical.CreateIndividualFeed(requestBody, app)
- if err != nil {
- slog.Error("Failed to create individual feed", "error", err)
- return c.JSON(http.StatusInternalServerError, "Failed to create individual feed")
- }
- return c.JSON(http.StatusOK, result)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(app),
- },
- })
+func addFeedRoutes(se *core.ServeEvent, pb *pocketbase.PocketBase) {
+ se.Router.POST("/api/feed", func(e *core.RequestEvent) error {
+ var feedCollection []model.FeedCollection
+ err := e.BindBody(&feedCollection)
if err != nil {
- return err
+ slog.Error("Failed to bind request body", "error", err)
+ return e.JSON(http.StatusBadRequest, "Invalid request body")
}
- return nil
+ result, err := ical.CreateIndividualFeed(feedCollection, pb)
+ if err != nil {
+ slog.Error("Failed to create individual feed", "error", err)
+ return e.JSON(http.StatusInternalServerError, "Failed to create individual feed")
+ }
+ return e.JSON(http.StatusOK, result)
})
- app.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodDelete,
- Path: "/api/feed",
- Handler: func(c echo.Context) error {
- token := c.QueryParam("token")
- err := feed.MarkFeedForDeletion(app.Dao(), token)
- if err != nil {
- return c.JSON(http.StatusNotFound, err)
- } else {
- return c.JSON(http.StatusOK, "Feed deleted")
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(app),
- },
- })
+ se.Router.DELETE("/api/feed", func(e *core.RequestEvent) error {
+ token := e.Request.URL.Query().Get("token")
+ err := feed.MarkFeedForDeletion(pb, token)
if err != nil {
- return err
+ return e.JSON(http.StatusNotFound, err)
+ } else {
+ return e.JSON(http.StatusOK, "Feed deleted")
}
- return nil
})
}
diff --git a/services/data-manager/service/addRoute.go b/services/data-manager/service/addRoute.go
index 562b45d..898f712 100644
--- a/services/data-manager/service/addRoute.go
+++ b/services/data-manager/service/addRoute.go
@@ -27,442 +27,211 @@ import (
"log/slog"
"net/http"
- "github.com/labstack/echo/v5"
"github.com/pocketbase/pocketbase/apis"
"github.com/pocketbase/pocketbase/core"
)
func AddRoutes(services serviceModel.Service) {
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/fetch/events",
- Handler: func(c echo.Context) error {
- savedEvents, err := v2.ParseEventsFromRemote(services.App)
+ services.App.OnServe().BindFunc(func(se *core.ServeEvent) error {
+ se.Router.GET("/api/fetch/events", func(e *core.RequestEvent) error {
+ savedEvents, err := v2.ParseEventsFromRemote(services.App)
+ if err != nil {
+ slog.Error("Failed to parse events from remote: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to parse events from remote")
+ } else {
+ return e.JSON(http.StatusOK, savedEvents)
+ }
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.GET("/api/fetch/daily/events", func(e *core.RequestEvent) error {
+ clock := time.RealClock{}
+ course.UpdateCourse(services, clock)
+ return e.JSON(http.StatusOK, "Daily events fetched")
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.GET("/api/fetch/group", func(e *core.RequestEvent) error {
+ seminarGroupString := e.Request.URL.Query().Get("seminarGroup")
+
+ if seminarGroupString == "" {
+ return e.JSON(http.StatusBadRequest, "Seminar group could not be empty")
+ } else {
+ //find seminar group by name
+ seminarGroup, err := services.CourseService.FindCourseByCourseName(seminarGroupString)
if err != nil {
- slog.Error("Failed to parse events from remote: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to parse events from remote")
- } else {
- return c.JSON(http.StatusOK, savedEvents)
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
-
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/fetch/daily/events",
- Handler: func(c echo.Context) error {
- clock := time.RealClock{}
- course.UpdateCourse(services, clock)
- return c.JSON(http.StatusOK, "Daily events fetched")
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
-
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/fetch/group",
- Handler: func(c echo.Context) error {
-
- seminarGroupString := c.QueryParam("seminarGroup")
-
- if seminarGroupString == "" {
- return c.JSON(http.StatusBadRequest, "Seminar group could not be empty")
- } else {
- //find seminar group by name
- seminarGroup, err := services.CourseService.FindCourseByCourseName(seminarGroupString)
- if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to find seminar group")
- }
-
- events, err := services.EventService.UpdateModulesForCourse(seminarGroup)
- if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to fetch seminar group")
- }
- return c.JSON(http.StatusOK, events)
+ return e.JSON(http.StatusBadRequest, "Failed to find seminar group")
}
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
-
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/fetch/groups",
- Handler: func(c echo.Context) error {
- groups, err := v1.FetchSeminarGroups(services.App)
+ events, err := services.EventService.UpdateModulesForCourse(seminarGroup)
if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to fetch seminar groups")
+ return e.JSON(http.StatusBadRequest, "Failed to fetch seminar group")
}
- return c.JSON(http.StatusOK, groups)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
+ return e.JSON(http.StatusOK, events)
+ }
+
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.GET("/api/fetch/groups", func(e *core.RequestEvent) error {
+ groups, err := v1.FetchSeminarGroups(services.App)
+ if err != nil {
+ slog.Error("Failed to fetch seminar groups: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to fetch seminar groups")
+ } else {
+ return e.JSON(http.StatusOK, groups)
+ }
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.GET("/api/fetch/sports", func(e *core.RequestEvent) error {
+ sportEvents, err := sport.FetchAndUpdateSportEvents(services.App)
+ if err != nil {
+ slog.Error("Failed to fetch sport events: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to fetch sport events")
+ } else {
+ return e.JSON(http.StatusOK, sportEvents)
+ }
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.DELETE("/api/modules", func(e *core.RequestEvent) error {
+ err := services.EventService.DeleteAllEvents()
+ if err != nil {
+ return e.JSON(http.StatusBadRequest, "Failed to delete events")
+ }
+ return e.JSON(http.StatusOK, "Events deleted")
+ }).Bind(apis.RequireSuperuserAuth())
+
+ se.Router.GET("/api/rooms", func(e *core.RequestEvent) error {
+ rooms, err := room.GetRooms(services.App)
+ if err != nil {
+ return e.JSON(http.StatusBadRequest, "Failed to get rooms")
+ }
+ return e.JSON(http.StatusOK, rooms)
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/fetch/sports",
- Handler: func(c echo.Context) error {
-
- sportEvents, err := sport.FetchAndUpdateSportEvents(services.App)
- if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to fetch sport events")
- }
- return c.JSON(http.StatusOK, sportEvents)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
+ se.Router.GET("/api/schedule/day", func(e *core.RequestEvent) error {
+ roomParam := e.Request.URL.Query().Get("room")
+ date := e.Request.URL.Query().Get("date")
+ roomSchedule, err := room.GetRoomScheduleForDay(services.App, roomParam, date)
+ if err != nil {
+ slog.Error("Failed to get room schedule for day: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get room schedule for day")
+ }
+ return e.JSON(http.StatusOK, roomSchedule)
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodDelete,
- Path: "/api/modules",
- Handler: func(c echo.Context) error {
- err := services.EventService.DeleteAllEvents()
- if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to delete events")
- }
- return c.JSON(http.StatusOK, "Events deleted")
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
+ se.Router.GET("/api/schedule", func(e *core.RequestEvent) error {
+ roomParam := e.Request.URL.Query().Get("room")
+ to := e.Request.URL.Query().Get("to")
+ from := e.Request.URL.Query().Get("from")
+ mapped := e.Request.URL.Query().Get("mapped")
+ roomSchedule, err := room.GetRoomSchedule(services.App, roomParam, from, to, mapped)
+ if err != nil {
+ slog.Error("Failed to get room schedule: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get room schedule")
+ }
+ return e.JSON(http.StatusOK, roomSchedule)
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/rooms",
- Handler: func(c echo.Context) error {
- rooms, err := room.GetRooms(services.App)
- if err != nil {
- return c.JSON(http.StatusBadRequest, "Failed to get rooms")
- }
- return c.JSON(http.StatusOK, rooms)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/rooms/free", func(e *core.RequestEvent) error {
+ from, err := time.ParseTime(e.Request.URL.Query().Get("from"))
+ if err != nil {
+ slog.Error("Failed to parse time: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to parse time")
+ }
+ to, err := time.ParseTime(e.Request.URL.Query().Get("to"))
+ if err != nil {
+ slog.Error("Failed to parse time: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to parse time")
+ }
+ rooms, err := room.GetFreeRooms(services.App, from, to)
+ if err != nil {
+ slog.Error("Failed to get free rooms: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get free rooms")
+ }
+ return e.JSON(http.StatusOK, rooms)
})
- if err != nil {
- return err
- }
- return nil
- })
- // API Endpoint to get all events for a specific room on a specific day
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/schedule/day",
- Handler: func(c echo.Context) error {
- roomParam := c.QueryParam("room")
- date := c.QueryParam("date")
- roomSchedule, err := room.GetRoomScheduleForDay(services.App, roomParam, date)
- if err != nil {
- slog.Error("Failed to get room schedule for day: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get room schedule for day")
- }
- return c.JSON(http.StatusOK, roomSchedule)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/course/modules", func(e *core.RequestEvent) error {
+ modules, err := services.EventService.GetModulesForCourseDistinct(
+ e.Request.URL.Query().Get("course"),
+ e.Request.URL.Query().Get("semester"),
+ )
+ if err != nil {
+ slog.Error("Failed to get modules for course and semester: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get modules for course and semester")
+ }
+ return e.JSON(http.StatusOK, modules)
})
- if err != nil {
- return err
- }
- return nil
- })
- // API Endpoint to create a new iCal feed
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/schedule",
- Handler: func(c echo.Context) error {
- roomParam := c.QueryParam("room")
- to := c.QueryParam("to")
- from := c.QueryParam("from")
- mapped := c.QueryParam("mapped")
- roomSchedule, err := room.GetRoomSchedule(services.App, roomParam, from, to, mapped)
- if err != nil {
- slog.Error("Failed to get room schedule:", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get room schedule")
- }
- return c.JSON(http.StatusOK, roomSchedule)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/modules", func(e *core.RequestEvent) error {
+ modules, err := services.EventService.GetAllModulesDistinct()
+ if err != nil {
+ slog.Error("Failed to get modules: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get modules")
+ }
+ return e.JSON(http.StatusOK, modules)
})
- if err != nil {
- return err
- }
- return nil
- })
- // API Endpoint to get all rooms that have no events in a specific time frame
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/rooms/free",
- Handler: func(c echo.Context) error {
- from, err := time.ParseTime(c.QueryParam("from"))
- if err != nil {
- slog.Error("Failed to parse time: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to parse time")
- }
- to, err := time.ParseTime(c.QueryParam("to"))
- if err != nil {
- slog.Error("Failed to parse time: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to parse time")
- }
- rooms, err := room.GetFreeRooms(services.App, from, to)
- if err != nil {
- slog.Error("Failed to get free rooms: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get free rooms")
- }
- return c.JSON(http.StatusOK, rooms)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/module", func(e *core.RequestEvent) error {
+ requestModule := e.Request.URL.Query().Get("uuid")
+ module, err := services.EventService.GetModuleByUUID(requestModule)
+ if err != nil {
+ slog.Error("Failed to get module: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get module")
+ }
+ return e.JSON(http.StatusOK, module)
})
- if err != nil {
- return err
- }
- return nil
- })
- addFeedRoutes(services.App)
-
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/course/modules",
- Handler: func(c echo.Context) error {
- modules, err := services.EventService.GetModulesForCourseDistinct(
- c.QueryParam("course"),
- c.QueryParam("semester"),
- )
-
- if err != nil {
- slog.Error("Failed to get modules for course and semester: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get modules for course and semester")
- } else {
- return c.JSON(http.StatusOK, modules)
+ se.Router.GET("/api/courses", func(e *core.RequestEvent) error {
+ semester := e.Request.URL.Query().Get("semester")
+ if semester == "" {
+ courses := services.CourseService.GetAllCourses()
+ return e.JSON(200, courses)
+ } else {
+ seminarGroups := services.CourseService.GetAllCoursesForSemester(semester)
+ courseStringList := make([]string, 0)
+ for _, seminarGroup := range seminarGroups {
+ courseStringList = append(courseStringList, seminarGroup.Course)
}
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ return e.JSON(200, courseStringList)
+ }
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/modules",
- Handler: func(c echo.Context) error {
- modules, err := services.EventService.GetAllModulesDistinct()
- if err != nil {
- slog.Error("Failed to get modules: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get modules")
- }
- return c.JSON(http.StatusOK, modules)
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/courses/events", func(e *core.RequestEvent) error {
+ semester := e.Request.URL.Query().Get("semester")
+ courses, err := services.CourseService.GetAllCoursesForSemesterWithEvents(semester)
+ if err != nil {
+ slog.Error("Failed to get courses for semester with events: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get courses for semester with events")
+ } else {
+ return e.JSON(http.StatusOK, courses)
+ }
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/module",
- Handler: func(c echo.Context) error {
- requestModule := c.QueryParam("uuid")
- module, err := services.EventService.GetModuleByUUID(requestModule)
- if err != nil {
- slog.Error("Failed to get module: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get module")
- } else {
- return c.JSON(http.StatusOK, module)
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
+ se.Router.GET("/api/events/types", func(e *core.RequestEvent) error {
+ eventTypes, err := services.EventService.GetEventTypes()
+ if err != nil {
+ slog.Error("Failed to get event types", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to get event types")
+ } else {
+ return e.JSON(http.StatusOK, eventTypes)
+ }
})
- if err != nil {
- return err
- }
- return nil
- })
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/courses",
- Handler: func(c echo.Context) error {
- semester := c.QueryParam("semester")
- if semester == "" {
- courses := services.CourseService.GetAllCourses()
- return c.JSON(200, courses)
- } else {
- seminarGroups := services.CourseService.GetAllCoursesForSemester(semester)
- courseStringList := make([]string, 0)
- for _, seminarGroup := range seminarGroups {
- courseStringList = append(courseStringList, seminarGroup.Course)
- }
- return c.JSON(200, courseStringList)
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
+ se.Router.DELETE("/api/events", func(e *core.RequestEvent) error {
+ err := services.EventService.DeleteAllEventsByCourseAndSemester(
+ e.Request.URL.Query().Get("course"),
+ e.Request.URL.Query().Get("semester"),
+ )
+ if err != nil {
+ slog.Error("Failed to delete events: ", "error", err)
+ return e.JSON(http.StatusBadRequest, "Failed to delete events")
+ } else {
+ return e.JSON(http.StatusOK, "Events deleted")
+ }
+ }).Bind(apis.RequireSuperuserAuth())
- // api end point to get all courses for a specific semester with courses that have events
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/courses/events",
- Handler: func(c echo.Context) error {
- semester := c.QueryParam("semester")
- courses, err := services.CourseService.GetAllCoursesForSemesterWithEvents(semester)
- if err != nil {
- slog.Error("Failed to get courses for semester with events: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get courses for semester with events")
- } else {
- return c.JSON(http.StatusOK, courses)
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
+ addFeedRoutes(se, services.App)
- // API Endpoint to get all eventTypes from the database distinct
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodGet,
- Path: "/api/events/types",
- Handler: func(c echo.Context) error {
- eventTypes, err := services.EventService.GetEventTypes()
- if err != nil {
- slog.Error("Failed to get event types", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to get event types")
- } else {
- return c.JSON(http.StatusOK, eventTypes)
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- },
- })
- if err != nil {
- return err
- }
- return nil
- })
-
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- _, err := e.Router.AddRoute(echo.Route{
- Method: http.MethodDelete,
- Path: "/api/events",
- Handler: func(c echo.Context) error {
- err := services.EventService.DeleteAllEventsByCourseAndSemester(
- c.QueryParam("course"),
- c.QueryParam("semester"),
- )
- if err != nil {
- slog.Error("Failed to delete events: ", "error", err)
- return c.JSON(http.StatusBadRequest, "Failed to delete events")
- } else {
- return c.JSON(http.StatusOK, "Events deleted")
- }
- },
- Middlewares: []echo.MiddlewareFunc{
- apis.ActivityLogger(services.App),
- apis.RequireAdminAuth(),
- },
- })
- if err != nil {
- return err
- }
- return nil
+ return se.Next()
})
}
diff --git a/services/data-manager/service/addSchedule.go b/services/data-manager/service/addSchedule.go
index 97f1ecf..72ee63c 100644
--- a/services/data-manager/service/addSchedule.go
+++ b/services/data-manager/service/addSchedule.go
@@ -17,8 +17,6 @@
package service
import (
- "github.com/pocketbase/pocketbase/core"
- "github.com/pocketbase/pocketbase/tools/cron"
"htwkalender/data-manager/model/serviceModel"
"htwkalender/data-manager/service/course"
"htwkalender/data-manager/service/feed"
@@ -32,56 +30,47 @@ import (
func AddSchedules(services serviceModel.Service) {
- services.App.OnBeforeServe().Add(func(e *core.ServeEvent) error {
- scheduler := cron.New()
+ services.App.Cron().MustAdd("updateCourses", "0 22 * * 0", func() {
+ slog.Info("Started updating courses schedule")
+ groups, err := v1.FetchSeminarGroups(services.App)
+ if err != nil {
+ slog.Warn("Failed to fetch seminar groups: ", "error", err)
+ }
+ slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(groups)), 10) + " seminar groups")
+ })
- // !! IMPORTANT !! CRON is based on UTC time zone so in Germany it is UTC+2 in summer and UTC+1 in winter
+ // Every day at 5am and 5pm update all courses (5 segments - minute, hour, day, month, weekday) "0 5,17 * * *"
+ // In Germany it is 7am and 7pm, syllabus gets updated twice a day at German 5:00 Uhr and 17:00 Uhr
+ services.App.Cron().MustAdd("updateEventsByCourse", "0 5,17 * * *", func() {
+ slog.Info("Started updating courses schedule")
+ clock := time.RealClock{}
+ course.UpdateCourse(services, clock)
+ })
- // Every sunday at 10pm update all courses (5 segments - minute, hour, day, month, weekday) "0 22 * * 0"
- scheduler.MustAdd("updateCourses", "0 22 * * 0", func() {
- slog.Info("Started updating courses schedule")
- groups, err := v1.FetchSeminarGroups(services.App)
- if err != nil {
- slog.Warn("Failed to fetch seminar groups: ", "error", err)
- }
- slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(groups)), 10) + " seminar groups")
- })
+ // Every sunday at 1am clean all courses (5 segments - minute, hour, day, month, weekday) "0 3 * * 0"
+ services.App.Cron().MustAdd("cleanFeeds", "0 1 * * 0", func() {
+ // clean feeds older than 6 months
+ slog.Info("Started cleaning feeds schedule")
+ feed.ClearFeeds(services.App, 6, time.RealClock{})
+ })
- // Every day at 5am and 5pm update all courses (5 segments - minute, hour, day, month, weekday) "0 5,17 * * *"
- // In Germany it is 7am and 7pm, syllabus gets updated twice a day at German 5:00 Uhr and 17:00 Uhr
- scheduler.MustAdd("updateEventsByCourse", "0 5,17 * * *", func() {
- slog.Info("Started updating courses schedule")
- clock := time.RealClock{}
- course.UpdateCourse(services, clock)
- })
+ // Every sunday at 3am fetch all sport events (5 segments - minute, hour, day, month, weekday) "0 2 * * 0"
+ services.App.Cron().MustAdd("fetchSportEvents", "0 3 * * 0", func() {
+ slog.Info("Started fetching sport events schedule")
+ sportEvents, err := sport.FetchAndUpdateSportEvents(services.App)
+ if err != nil {
+ slog.Error("Failed to fetch and save sport events:", "error", err)
+ }
+ slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(sportEvents)), 10) + " sport events")
+ })
- // Every sunday at 1am clean all courses (5 segments - minute, hour, day, month, weekday) "0 3 * * 0"
- scheduler.MustAdd("cleanFeeds", "0 1 * * 0", func() {
- // clean feeds older than 6 months
- slog.Info("Started cleaning feeds schedule")
- feed.ClearFeeds(services.App.Dao(), 6, time.RealClock{})
- })
-
- // Every sunday at 3am fetch all sport events (5 segments - minute, hour, day, month, weekday) "0 2 * * 0"
- scheduler.MustAdd("fetchSportEvents", "0 3 * * 0", func() {
- slog.Info("Started fetching sport events schedule")
- sportEvents, err := sport.FetchAndUpdateSportEvents(services.App)
- if err != nil {
- slog.Error("Failed to fetch and save sport events:", "error", err)
- }
- slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(sportEvents)), 10) + " sport events")
- })
-
- //fetch all events for semester and delete from remote this should be done every sunday at 2am
- scheduler.MustAdd("fetchEvents", "0 22 * * 6", func() {
- savedEvents, err := v2.FetchAllEventsAndSave(services.App, time.RealClock{})
- if err != nil {
- slog.Error("Failed to fetch and save events: ", "error", err)
- } else {
- slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(savedEvents)), 10) + " events")
- }
- })
- scheduler.Start()
- return nil
+ //fetch all events for semester and delete from remote this should be done every sunday at 2am
+ services.App.Cron().MustAdd("fetchEvents", "0 22 * * 6", func() {
+ savedEvents, err := v2.FetchAllEventsAndSave(services.App, time.RealClock{})
+ if err != nil {
+ slog.Error("Failed to fetch and save events: ", "error", err)
+ } else {
+ slog.Info("Successfully fetched " + strconv.FormatInt(int64(len(savedEvents)), 10) + " events")
+ }
})
}
diff --git a/services/data-manager/service/db/dbEvents.go b/services/data-manager/service/db/dbEvents.go
index 95b5698..4d43826 100644
--- a/services/data-manager/service/db/dbEvents.go
+++ b/services/data-manager/service/db/dbEvents.go
@@ -19,7 +19,7 @@ package db
import (
"fmt"
"github.com/google/uuid"
- "github.com/pocketbase/pocketbase/daos"
+ "github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/types"
"htwkalender/data-manager/model"
"log/slog"
@@ -29,47 +29,212 @@ import (
"github.com/pocketbase/pocketbase"
)
-func SaveSeminarGroupEvents(seminarGroup model.SeminarGroup, app *pocketbase.PocketBase) ([]model.Event, error) {
- var toBeSavedEvents model.Events
- var savedRecords model.Events
+var _ core.RecordProxy = (*Event)(nil)
- // check if event is already in database and add to toBeSavedEvents if not
- for _, event := range seminarGroup.Events {
- event = event.SetCourse(seminarGroup.Course)
- existsInDatabase, err := findEventByDayWeekStartEndNameCourse(event, seminarGroup.Course, app.Dao())
- alreadyAddedToSave := toBeSavedEvents.Contains(event)
-
- if err != nil {
- return nil, err
- }
-
- if !existsInDatabase && !alreadyAddedToSave {
- toBeSavedEvents = append(toBeSavedEvents, event)
- }
- }
-
- // create record for each event that's not already in the database
- for _, event := range toBeSavedEvents {
- event.MarkAsNew()
- // auto mapping for event fields to record fields
- err := app.Dao().Save(&event)
- if err != nil {
- return nil, err
- } else {
- savedRecords = append(savedRecords, event)
- }
- }
-
- return savedRecords, nil
+type Event struct {
+ core.BaseRecordProxy
}
-func SaveEvents(events []model.Event, txDao *daos.Dao) ([]model.Event, error) {
+type Events []*Event
+
+func (event *Event) GetDay() string {
+ return event.GetString("Day")
+}
+
+func (event *Event) SetDay(day string) {
+ event.Set("Day", day)
+}
+
+func (event *Event) GetWeek() string {
+ return event.GetString("Week")
+}
+
+func (event *Event) SetWeek(week string) {
+ event.Set("Week", week)
+}
+
+func (event *Event) GetName() string {
+ return event.GetString("Name")
+}
+
+func (event *Event) SetName(name string) {
+ event.Set("Name", name)
+}
+
+func (event *Event) GetEventType() string {
+ return event.GetString("EventType")
+}
+
+func (event *Event) SetEventType(eventType string) {
+ event.Set("EventType", eventType)
+}
+
+func (event *Event) GetProf() string {
+ return event.GetString("Prof")
+}
+
+func (event *Event) SetProf(prof string) {
+ event.Set("Prof", prof)
+}
+
+func (event *Event) GetRooms() string {
+ return event.GetString("Rooms")
+}
+
+func (event *Event) SetRooms(rooms string) {
+ event.Set("Rooms", rooms)
+}
+
+func (event *Event) GetNotes() string {
+ return event.GetString("Notes")
+}
+
+func (event *Event) SetNotes(notes string) {
+ event.Set("Notes", notes)
+}
+
+func (event *Event) GetBookedAt() string {
+ return event.GetString("BookedAt")
+}
+
+func (event *Event) SetBookedAt(bookedAt string) {
+ event.Set("BookedAt", bookedAt)
+}
+
+func (event *Event) GetCourse() string {
+ return event.GetString("course")
+}
+
+func (event *Event) SetCourse(course string) {
+ event.Set("course", course)
+}
+
+func (event *Event) GetSemester() string {
+ return event.GetString("semester")
+}
+
+func (event *Event) SetSemester(semester string) {
+ event.Set("semester", semester)
+}
+
+func (event *Event) GetUUID() string {
+ return event.GetString("uuid")
+}
+
+func (event *Event) SetUUID(uuid string) {
+ event.Set("uuid", uuid)
+}
+
+func (event *Event) GetStart() types.DateTime {
+ return event.GetDateTime("start")
+}
+
+func (event *Event) SetStart(start types.DateTime) {
+ event.Set("start", start)
+}
+
+func (event *Event) GetEnd() types.DateTime {
+ return event.GetDateTime("end")
+}
+
+func (event *Event) SetEnd(end types.DateTime) {
+ event.Set("end", end)
+}
+
+func (event *Event) GetCompulsory() string {
+ return event.GetString("Compulsory")
+}
+
+func (event *Event) SetCompulsory(compulsory string) {
+ event.Set("Compulsory", compulsory)
+}
+
+func (event *Event) GetCreated() types.DateTime {
+ return event.GetDateTime("created")
+}
+
+func (event *Event) SetCreated(created types.DateTime) {
+ event.Set("created", created)
+}
+
+func (event *Event) GetUpdated() types.DateTime {
+ return event.GetDateTime("updated")
+}
+
+func (event *Event) SetUpdated(updated types.DateTime) {
+ event.Set("updated", updated)
+}
+
+func newEvent(record *core.Record) *Event {
+ return &Event{
+ BaseRecordProxy: core.BaseRecordProxy{Record: record},
+ }
+}
+
+func NewEvent(collection *core.Collection, event model.Event) (*Event, error) {
+ // Create a new Event instance
+ if collection.Name != "events" {
+ return nil, core.ErrInvalidFieldValue
+ }
+
+ record := core.NewRecord(collection)
+ record.Set("id:autogenerate", "")
+
+ ev := newEvent(record)
+ // Set the fields from the model
+ ev.SetDay(event.Day)
+ ev.SetWeek(event.Week)
+ ev.SetStart(event.Start)
+ ev.SetEnd(event.End)
+ ev.SetName(event.Name)
+ ev.SetEventType(event.EventType)
+ ev.SetProf(event.Prof)
+ ev.SetRooms(event.Rooms)
+ ev.SetNotes(event.Notes)
+ ev.SetBookedAt(event.BookedAt)
+ ev.SetCourse(event.Course)
+ ev.SetSemester(event.Semester)
+ ev.SetUUID(uuid.NewString())
+ return ev, nil
+}
+
+func (event *Event) ToModel() model.Event {
+ return model.Event{
+ Day: event.GetDay(),
+ Week: event.GetWeek(),
+ Start: event.GetStart(),
+ End: event.GetEnd(),
+ Name: event.GetName(),
+ EventType: event.GetEventType(),
+ Prof: event.GetProf(),
+ Rooms: event.GetRooms(),
+ Notes: event.GetNotes(),
+ BookedAt: event.GetBookedAt(),
+ Course: event.GetCourse(),
+ Semester: event.GetSemester(),
+ UUID: event.GetUUID(),
+ }
+}
+
+func (events *Events) ToEvents() model.Events {
+ var result model.Events
+ for _, event := range *events {
+ result = append(result, event.ToModel())
+ }
+ return result
+}
+
+func SaveSeminarGroupEvents(seminarGroup model.SeminarGroup, base *pocketbase.PocketBase) (model.Events, error) {
+ return SaveEvents(seminarGroup.Events, base.App)
+}
+
+func SaveEvents(events []model.Event, app core.App) (model.Events, error) {
var toBeSavedEvents model.Events
var savedRecords model.Events
// check if event is already in database and add to toBeSavedEvents if not
for _, event := range events {
- existsInDatabase, err := findEventByDayWeekStartEndNameCourse(event, event.Course, txDao)
+ existsInDatabase, err := findEventByDayWeekStartEndNameCourse(event, event.Course, app)
alreadyAddedToSave := toBeSavedEvents.Contains(event)
if err != nil {
@@ -80,26 +245,45 @@ func SaveEvents(events []model.Event, txDao *daos.Dao) ([]model.Event, error) {
toBeSavedEvents = append(toBeSavedEvents, event)
}
}
+
+ collection, err := app.FindCollectionByNameOrId("events")
+ if err != nil {
+ return nil, err
+ }
+
// create record for each event that's not already in the database
for _, event := range toBeSavedEvents {
- event.MarkAsNew()
// auto mapping for event fields to record fields
- err := txDao.Save(&event)
- if err != nil {
- return nil, err
+ savedEvent, saveErr := saveEvent(collection, event, app)
+ if saveErr != nil {
+ return nil, saveErr
} else {
- savedRecords = append(savedRecords, event)
+ savedRecords = append(savedRecords, savedEvent.ToModel())
}
}
return savedRecords, nil
}
+func saveEvent(collection *core.Collection, event model.Event, app core.App) (*Event, error) {
+ dbEvent, recordErr := NewEvent(collection, event)
+ if recordErr != nil {
+ return nil, recordErr
+ }
+ // auto mapping for event fields to record fields
+ dbErr := app.Save(dbEvent)
+ if dbErr != nil {
+ return nil, dbErr
+ }
+
+ return dbEvent, nil
+}
+
// check if event is already in database and return true if it is and false if it's not
-func findEventByDayWeekStartEndNameCourse(event model.Event, course string, dao *daos.Dao) (bool, error) {
+func findEventByDayWeekStartEndNameCourse(event model.Event, course string, app core.App) (bool, error) {
var dbEvent model.Event
- err := dao.DB().Select("*").From("events").
+ err := app.DB().Select("*").From("events").
Where(dbx.NewExp(
"Day = {:day} AND "+
"Week = {:week} AND "+
@@ -191,7 +375,7 @@ func GetPlanForModules(app *pocketbase.PocketBase, modules []string) (model.Even
var selectedModulesQuery = buildIcalQueryForModules(moduleBatch)
// get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").Where(selectedModulesQuery).OrderBy("start").All(&events)
+ err := app.DB().Select("*").From("events").Where(selectedModulesQuery).OrderBy("start").All(&events)
if err != nil {
return nil, err
}
@@ -204,20 +388,7 @@ func GetAllEventsForCourse(app *pocketbase.PocketBase, course string) (model.Eve
var events model.Events
// get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course}", dbx.Params{"course": course})).All(&events)
- if err != nil {
- slog.Error("Error while getting events from database: ", "error", err)
- return nil, fmt.Errorf("error while getting events from database for course %s", course)
- }
-
- return events, nil
-}
-
-func GetAllEventsForCourseAndSemester(app *pocketbase.PocketBase, course string, semester string) (model.Events, error) {
- var events model.Events
-
- // get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("course = {:course}", dbx.Params{"course": course})).All(&events)
if err != nil {
slog.Error("Error while getting events from database: ", "error", err)
return nil, fmt.Errorf("error while getting events from database for course %s", course)
@@ -230,7 +401,7 @@ func GetAllModulesForCourse(app *pocketbase.PocketBase, course string, semester
var events model.Events
// get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).GroupBy("Name").Distinct(true).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).GroupBy("Name").Distinct(true).All(&events)
if err != nil {
slog.Error("Error while getting events from database: ", "error", err)
return nil, fmt.Errorf("error while getting events from database for course %s and semester %s", course, semester)
@@ -242,7 +413,7 @@ func GetAllModulesForCourse(app *pocketbase.PocketBase, course string, semester
func GetAllModulesDistinctByNameAndCourse(app *pocketbase.PocketBase) ([]model.ModuleDTO, error) {
var modules []model.ModuleDTO
- err := app.Dao().DB().Select("Name", "EventType", "Prof", "course", "semester", "uuid").From("events").GroupBy("Name", "Course").Distinct(true).All(&modules)
+ err := app.DB().Select("Name", "EventType", "Prof", "course", "semester", "uuid").From("events").GroupBy("Name", "Course").Distinct(true).All(&modules)
if err != nil {
slog.Error("Error while getting events from database: ", "error", err)
return nil, fmt.Errorf("error while getting events distinct by name and course from data")
@@ -251,8 +422,8 @@ func GetAllModulesDistinctByNameAndCourse(app *pocketbase.PocketBase) ([]model.M
return modules, nil
}
-func DeleteAllEventsByCourse(dao *daos.Dao, course string, semester string) error {
- _, err := dao.DB().Delete("events", dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute()
+func DeleteAllEventsByCourse(base *pocketbase.PocketBase, course string, semester string) error {
+ _, err := base.DB().Delete("events", dbx.NewExp("course = {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute()
if err != nil {
return err
@@ -260,8 +431,8 @@ func DeleteAllEventsByCourse(dao *daos.Dao, course string, semester string) erro
return nil
}
-func DeleteAllEventsRatherThenCourse(dao *daos.Dao, course string, semester string) error {
- _, err := dao.DB().Delete("events", dbx.NewExp("course != {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute()
+func DeleteAllEventsRatherThenCourse(app core.App, course string, semester string) error {
+ _, err := app.DB().Delete("events", dbx.NewExp("course != {:course} AND semester = {:semester}", dbx.Params{"course": course, "semester": semester})).Execute()
if err != nil {
return err
@@ -269,9 +440,9 @@ func DeleteAllEventsRatherThenCourse(dao *daos.Dao, course string, semester stri
return nil
}
-func DeleteAllEvents(app *pocketbase.PocketBase) error {
+func DeleteAllEvents(app core.App) error {
- _, err := app.Dao().DB().Delete("events", dbx.NewExp("1=1")).Execute()
+ _, err := app.DB().Delete("events", dbx.NewExp("1=1")).Execute()
if err != nil {
return err
@@ -283,7 +454,7 @@ func DeleteAllEvents(app *pocketbase.PocketBase) error {
func FindModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, error) {
var module model.Module
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("uuid = {:uuid}", dbx.Params{"uuid": uuid})).One(&module)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("uuid = {:uuid}", dbx.Params{"uuid": uuid})).One(&module)
if err != nil {
return model.Module{}, err
}
@@ -294,7 +465,7 @@ func FindModuleByUUID(app *pocketbase.PocketBase, uuid string) (model.Module, er
func FindAllEventsByModule(app *pocketbase.PocketBase, module model.Module) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:moduleName} AND course = {:course}", dbx.Params{"moduleName": module.Name, "course": module.Course})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Name = {:moduleName} AND course = {:course}", dbx.Params{"moduleName": module.Name, "course": module.Course})).All(&events)
if err != nil {
return nil, err
}
@@ -305,7 +476,7 @@ func FindAllEventsByModule(app *pocketbase.PocketBase, module model.Module) (mod
func GetAllModulesByNameAndDateRange(app *pocketbase.PocketBase, name string, startDate time.Time, endDate time.Time) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Name = {:name} AND Start >= {:startDate} AND End <= {:endDate}", dbx.Params{"name": name, "startDate": startDate, "endDate": endDate})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Name = {:name} AND Start >= {:startDate} AND End <= {:endDate}", dbx.Params{"name": name, "startDate": startDate, "endDate": endDate})).All(&events)
if err != nil {
return nil, err
}
@@ -355,7 +526,7 @@ func GetEventsThatCollideWithTimeRange(app *pocketbase.PocketBase, from time.Tim
func GetEventsThatStartBeforeAndEndAfter(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start <= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).Distinct(true).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Start <= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).Distinct(true).All(&events)
if err != nil {
return nil, err
@@ -367,7 +538,7 @@ func GetEventsThatStartBeforeAndEndAfter(app *pocketbase.PocketBase, from types.
func GetEventsThatStartAfterAndEndBefore(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End <= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End <= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
if err != nil {
return nil, err
@@ -379,7 +550,7 @@ func GetEventsThatStartAfterAndEndBefore(app *pocketbase.PocketBase, from types.
func GetEventsThatStartBeforeAndEndBefore(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start <= {:startDate} AND End <= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Start <= {:startDate} AND End <= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
if err != nil {
return nil, err
@@ -391,7 +562,7 @@ func GetEventsThatStartBeforeAndEndBefore(app *pocketbase.PocketBase, from types
func GetAllEventTypes(app *pocketbase.PocketBase) ([]model.EventType, error) {
var eventTypes []model.EventType
- err := app.Dao().DB().Select("EventType").From("events").GroupBy("EventType").Distinct(true).All(&eventTypes)
+ err := app.DB().Select("EventType").From("events").GroupBy("EventType").Distinct(true).All(&eventTypes)
if err != nil {
return nil, err
}
@@ -401,7 +572,7 @@ func GetAllEventTypes(app *pocketbase.PocketBase) ([]model.EventType, error) {
func GetEventsThatStartAfterAndEndAfter(app *pocketbase.PocketBase, from types.DateTime, to types.DateTime) (model.Events, error) {
var events model.Events
- err := app.Dao().DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
+ err := app.DB().Select("*").From("events").Where(dbx.NewExp("Start >= {:startDate} AND End >= {:endDate} AND Start <= {:endDate} AND End >= {:startDate}", dbx.Params{"startDate": from, "endDate": to})).All(&events)
if err != nil {
return nil, err
@@ -412,7 +583,7 @@ func GetEventsThatStartAfterAndEndAfter(app *pocketbase.PocketBase, from types.D
func DeleteEvents(list model.Events, app *pocketbase.PocketBase) error {
for _, event := range list {
- err := app.Dao().Delete(&event)
+ err := app.Delete(&event)
if err != nil {
return err
}
diff --git a/services/data-manager/service/db/dbFeeds.go b/services/data-manager/service/db/dbFeeds.go
index 3def9b0..483833b 100644
--- a/services/data-manager/service/db/dbFeeds.go
+++ b/services/data-manager/service/db/dbFeeds.go
@@ -20,26 +20,120 @@ import (
"errors"
"github.com/pocketbase/dbx"
"github.com/pocketbase/pocketbase"
- "github.com/pocketbase/pocketbase/daos"
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tools/types"
"htwkalender/data-manager/model"
"time"
)
-func SaveFeed(feed model.Feed, collection *models.Collection, app *pocketbase.PocketBase) (*models.Record, error) {
- record := models.NewRecord(collection)
- record.Set("modules", feed.Modules)
- err := app.Dao().SaveRecord(record)
+var _ core.RecordProxy = (*Feed)(nil)
- if err != nil {
- return nil, err
+type Feed struct {
+ core.BaseRecordProxy
+}
+
+type Feeds []*Feed
+
+// Getter and Setter for the Feed struct
+
+func (f *Feed) GetModules() string {
+ return f.GetString("modules")
+}
+
+func (f *Feed) SetModules(modules string) {
+ f.Set("modules", modules)
+}
+
+func (f *Feed) GetRetrieved() types.DateTime {
+ return f.GetDateTime("retrieved")
+}
+
+func (f *Feed) SetRetrieved(retrieved types.DateTime) {
+ f.Set("retrieved", retrieved)
+}
+
+func (f *Feed) GetDeleted() bool {
+ return f.GetBool("deleted")
+}
+
+func (f *Feed) SetDeleted(deleted bool) {
+ f.Set("deleted", deleted)
+}
+
+func (f *Feed) GetId() string {
+ return f.GetString("id")
+}
+
+func (f *Feed) SetId(id string) {
+ f.Set("id", id)
+}
+
+func (f *Feed) GetCreated() types.DateTime {
+ return f.GetDateTime("created")
+}
+
+func (f *Feed) SetCreated(created time.Time) {
+ f.Set("created", created)
+}
+
+func (f *Feed) GetUpdated() types.DateTime {
+ return f.GetDateTime("updated")
+}
+
+func newFeed(record *core.Record) *Feed {
+ return &Feed{
+ BaseRecordProxy: core.BaseRecordProxy{Record: record},
}
- return record, nil
+}
+
+func NewFeed(collection *core.Collection, feed model.Feed) (*Feed, error) {
+ // Create a new Feed instance
+ if collection.Name != "feeds" {
+ return nil, core.ErrInvalidFieldValue
+ }
+
+ record := core.NewRecord(collection)
+ record.Set("id:autogenerate", "")
+
+ dbFeed := newFeed(record)
+ dbFeed.SetModules(feed.Modules)
+ dbFeed.SetRetrieved(feed.Retrieved)
+ dbFeed.SetDeleted(feed.Deleted)
+
+ return dbFeed, nil
+}
+
+func (f *Feed) ToModel() model.Feed {
+ return model.Feed{
+ Modules: f.GetModules(),
+ Retrieved: f.GetRetrieved(),
+ Created: f.GetCreated(),
+ Updated: f.GetUpdated(),
+ Deleted: f.GetDeleted(),
+ BaseModel: core.BaseModel{
+ Id: f.GetId(),
+ },
+ }
+}
+
+func SaveFeed(feed model.Feed, collection *core.Collection, app *pocketbase.PocketBase) (model.Feed, error) {
+ dbFeed, recordErr := NewFeed(collection, feed)
+ if recordErr != nil {
+ return model.Feed{}, recordErr
+ }
+
+ // Save the record to the database
+ saveErr := app.Save(dbFeed)
+ if saveErr != nil {
+ return model.Feed{}, saveErr
+ }
+
+ return dbFeed.ToModel(), nil
}
func FindFeedByToken(app *pocketbase.PocketBase, token string) (*model.Feed, error) {
- record, err := app.Dao().FindRecordById("feeds", token)
+ record, err := app.FindRecordById("feeds", token)
if err != nil {
return nil, err
@@ -53,15 +147,15 @@ func FindFeedByToken(app *pocketbase.PocketBase, token string) (*model.Feed, err
//update retrieved time if the is not marked as deleted
if !record.GetBool("deleted") {
record.Set("retrieved", time.Now())
- err = app.Dao().SaveRecord(record)
+ err = app.Save(record)
}
return &feed, err
}
-func DeleteFeed(db *daos.Dao, feedId string) error {
+func DeleteFeed(base *pocketbase.PocketBase, feedId string) error {
- sqlResult, err := db.DB().Delete("feeds", dbx.NewExp("id = {:id}", dbx.Params{"id": feedId})).Execute()
+ sqlResult, err := base.DB().Delete("feeds", dbx.NewExp("id = {:id}", dbx.Params{"id": feedId})).Execute()
var deletedRows int64
if sqlResult != nil {
deletedRows, _ = sqlResult.RowsAffected()
@@ -78,19 +172,19 @@ func DeleteFeed(db *daos.Dao, feedId string) error {
}
}
-func GetAllFeeds(db *daos.Dao) ([]model.Feed, error) {
+func GetAllFeeds(base *pocketbase.PocketBase) ([]model.Feed, error) {
var feeds []model.Feed
- err := db.DB().Select("*").From("feeds").All(&feeds)
+ err := base.DB().Select("*").From("feeds").All(&feeds)
if err != nil {
return nil, err
}
return feeds, nil
}
-func MarkForDelete(db *daos.Dao, token string) error {
+func MarkForDelete(base *pocketbase.PocketBase, token string) error {
// get record from db
feed := model.Feed{}
- err := db.DB().Select("*").From("feeds").Where(dbx.NewExp("id = {:id}", dbx.Params{"id": token})).One(&feed)
+ err := base.DB().Select("*").From("feeds").Where(dbx.NewExp("id = {:id}", dbx.Params{"id": token})).One(&feed)
if err != nil {
return err
}
@@ -99,7 +193,7 @@ func MarkForDelete(db *daos.Dao, token string) error {
feed.Modules = "[\n {\n \"uuid\": \"\",\n \"name\": \"Deleted\",\n \"course\": \"\",\n \"userDefinedName\": \"Deleted\",\n \"reminder\": false\n }\n]"
// save record
- err = db.Save(&feed)
+ err = base.Save(&feed)
if err != nil {
return err
}
diff --git a/services/data-manager/service/db/dbFunctions.go b/services/data-manager/service/db/dbFunctions.go
deleted file mode 100644
index 05cd48b..0000000
--- a/services/data-manager/service/db/dbFunctions.go
+++ /dev/null
@@ -1,27 +0,0 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
-package db
-
-import (
- "github.com/pocketbase/pocketbase"
- "github.com/pocketbase/pocketbase/models"
-)
-
-func FindCollection(app *pocketbase.PocketBase, collectionName string) (*models.Collection, error) {
- collection, dbError := app.Dao().FindCollectionByNameOrId(collectionName)
- return collection, dbError
-}
diff --git a/services/data-manager/service/db/dbGroups.go b/services/data-manager/service/db/dbGroups.go
index eef2641..fb2e32d 100644
--- a/services/data-manager/service/db/dbGroups.go
+++ b/services/data-manager/service/db/dbGroups.go
@@ -1,162 +1,252 @@
-//Calendar implementation for the HTWK Leipzig timetable. Evaluation and display of the individual dates in iCal format.
-//Copyright (C) 2024 HTWKalender support@htwkalender.de
-
-//This program is free software: you can redistribute it and/or modify
-//it under the terms of the GNU Affero General Public License as published by
-//the Free Software Foundation, either version 3 of the License, or
-//(at your option) any later version.
-
-//This program is distributed in the hope that it will be useful,
-//but WITHOUT ANY WARRANTY; without even the implied warranty of
-//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-//GNU Affero General Public License for more details.
-
-//You should have received a copy of the GNU Affero General Public License
-//along with this program. If not, see .
-
package db
import (
"github.com/pocketbase/dbx"
- "github.com/pocketbase/pocketbase"
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
+ "github.com/pocketbase/pocketbase/tools/types"
"htwkalender/data-manager/model"
"log/slog"
)
-type SeminarGroup struct {
- University string `db:"university" json:"university"`
- GroupShortcut string `db:"shortcut" json:"shortcut"`
- GroupId string `db:"groupId" json:"groupId"`
- Course string `db:"course" json:"course"`
- Faculty string `db:"faculty" json:"faculty"`
- FacultyId string `db:"facultyId" json:"facultyId"`
- Semester string `db:"semester" json:"semester"`
- models.BaseModel
-}
-
-func (s *SeminarGroup) TableName() string {
- return "groups"
-}
-
-// UniqueKey Should be same as unique constraint in the database
-func (s *SeminarGroup) UniqueKey() string {
- return s.Course + s.Semester
-}
-
-func (s *SeminarGroup) toSeminarGroupModel() model.SeminarGroup {
- return model.SeminarGroup{
- University: s.University,
- GroupShortcut: s.GroupShortcut,
- GroupId: s.GroupId,
- Course: s.Course,
- Faculty: s.Faculty,
- FacultyId: s.FacultyId,
- Semester: s.Semester,
- }
-}
-
-func (s *SeminarGroups) toSeminarGroupModels() []model.SeminarGroup {
- var seminarGroups []model.SeminarGroup
- for _, group := range *s {
- seminarGroups = append(seminarGroups, group.toSeminarGroupModel())
- }
- return seminarGroups
-}
+// Ensure SeminarGroup satisfies RecordProxy
+var _ core.RecordProxy = (*SeminarGroup)(nil)
type SeminarGroups []*SeminarGroup
-func SaveGroups(seminarGroups SeminarGroups, app *pocketbase.PocketBase) (SeminarGroups, error) {
-
- // delete all groups from the database
- execute, err := app.Dao().DB().Delete("groups", dbx.NewExp("1 = 1")).Execute()
- if err != nil {
- return nil, err
- }
- rowCount, _ := execute.RowsAffected()
-
- savedGroups := SeminarGroups{}
- for _, group := range seminarGroups {
- saveErr := app.Dao().Save(group)
- if saveErr != nil {
- return nil, saveErr
- }
- savedGroups = append(savedGroups, group)
- }
- slog.Info("Saved all groups to the database", "insert", len(savedGroups), "deleted", rowCount)
-
- return savedGroups, nil
+type SeminarGroup struct {
+ core.BaseRecordProxy
}
-func GetAllCourses(app *pocketbase.PocketBase) []string {
+// Getter and Setter methods
- var courses []struct {
- CourseShortcut string `db:"course" json:"course"`
- }
-
- // get all rooms from event records in the events collection
- err := app.Dao().DB().Select("course").From("groups").All(&courses)
- if err != nil {
- slog.Error("Error while getting groups from database: ", "error", err)
- return []string{}
- }
-
- var courseArray []string
-
- for _, course := range courses {
- courseArray = append(courseArray, course.CourseShortcut)
- }
-
- return courseArray
+func (s *SeminarGroup) University() string {
+ return s.GetString("university")
+}
+func (s *SeminarGroup) SetUniversity(val string) {
+ s.Set("university", val)
}
-func GetAllCoursesForSemester(app *pocketbase.PocketBase, semester string) []model.SeminarGroup {
-
- var courses SeminarGroups
-
- // get all courses for a specific semester
- err := app.Dao().DB().Select("*").From("groups").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).All(&courses)
- if err != nil {
- slog.Error("Error while getting groups from database: ", "error", err)
- return nil
- }
-
- return courses.toSeminarGroupModels()
-
+func (s *SeminarGroup) GroupShortcut() string {
+ return s.GetString("shortcut")
+}
+func (s *SeminarGroup) SetGroupShortcut(val string) {
+ s.Set("shortcut", val)
}
-func GetAllCoursesForSemesterWithEvents(app *pocketbase.PocketBase, semester string) ([]string, error) {
+func (s *SeminarGroup) GroupId() string {
+ return s.GetString("groupId")
+}
+func (s *SeminarGroup) SetGroupId(val string) {
+ s.Set("groupId", val)
+}
- var courses []struct {
- CourseShortcut string `db:"course" json:"course"`
+func (s *SeminarGroup) Course() string {
+ return s.GetString("course")
+}
+func (s *SeminarGroup) SetCourse(val string) {
+ s.Set("course", val)
+}
+
+func (s *SeminarGroup) Faculty() string {
+ return s.GetString("faculty")
+}
+func (s *SeminarGroup) SetFaculty(val string) {
+ s.Set("faculty", val)
+}
+
+func (s *SeminarGroup) FacultyId() string {
+ return s.GetString("facultyId")
+}
+func (s *SeminarGroup) SetFacultyId(val string) {
+ s.Set("facultyId", val)
+}
+
+func (s *SeminarGroup) Semester() string {
+ return s.GetString("semester")
+}
+func (s *SeminarGroup) SetSemester(val string) {
+ s.Set("semester", val)
+}
+
+func (s *SeminarGroup) Created() types.DateTime {
+ return s.GetDateTime("created")
+}
+
+func (s *SeminarGroup) Updated() types.DateTime {
+ return s.GetDateTime("updated")
+}
+
+func (s *SeminarGroup) UniqueKey() string {
+ return s.Course() + s.Semester()
+}
+
+func NewSeminarGroup(collection *core.Collection, group model.SeminarGroup) (*SeminarGroup, error) {
+ // Create a new SeminarGroup instance
+ if collection.Name != "groups" {
+ return nil, core.ErrInvalidFieldValue
}
- // get all courses from events distinct for a specific semester
- err := app.Dao().DB().Select("course").From("events").Where(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).Distinct(true).All(&courses)
+ record := core.NewRecord(collection)
+ record.Set("id:autogenerate", "")
+
+ sg := newSeminarGroup(record)
+ // Set the fields from the model
+ sg.SetUniversity(group.University)
+ sg.SetGroupShortcut(group.GroupShortcut)
+ sg.SetGroupId(group.GroupId)
+ sg.SetCourse(group.Course)
+ sg.SetFaculty(group.Faculty)
+ sg.SetFacultyId(group.FacultyId)
+ sg.SetSemester(group.Semester)
+
+ return sg, nil
+}
+
+func newSeminarGroup(record *core.Record) *SeminarGroup {
+ sg := &SeminarGroup{}
+ sg.SetProxyRecord(record)
+ return sg
+}
+
+// ToModel Model conversion
+func (s *SeminarGroup) ToModel() model.SeminarGroup {
+ return model.SeminarGroup{
+ University: s.University(),
+ GroupShortcut: s.GroupShortcut(),
+ GroupId: s.GroupId(),
+ Course: s.Course(),
+ Faculty: s.Faculty(),
+ FacultyId: s.FacultyId(),
+ Semester: s.Semester(),
+ }
+}
+
+func (s *SeminarGroups) ToModelArray() []model.SeminarGroup {
+ models := make([]model.SeminarGroup, len(*s))
+ for i, group := range *s {
+ models[i] = group.ToModel()
+ }
+ return models
+}
+
+func (s *SeminarGroup) FromModel(m model.SeminarGroup) {
+ s.SetUniversity(m.University)
+ s.SetGroupShortcut(m.GroupShortcut)
+ s.SetGroupId(m.GroupId)
+ s.SetCourse(m.Course)
+ s.SetFaculty(m.Faculty)
+ s.SetFacultyId(m.FacultyId)
+ s.SetSemester(m.Semester)
+}
+
+func (s *SeminarGroups) FromModelArray(m model.SeminarGroups) SeminarGroups {
+ groups := make(SeminarGroups, len(m))
+ for i, group := range m {
+ groups[i] = &SeminarGroup{}
+ groups[i].FromModel(group)
+ }
+ return groups
+}
+
+func FindCourseByCourseName(app core.App, courseName string) (model.SeminarGroup, error) {
+ group := &SeminarGroup{}
+ err := app.RecordQuery("groups").
+ AndWhere(dbx.NewExp("course = {:course}", dbx.Params{"course": courseName})).
+ Limit(1).
+ One(group)
+
+ if err != nil {
+ return model.SeminarGroup{}, err
+ }
+
+ return group.ToModel(), nil
+}
+
+func GetAllCourses(app core.App) ([]string, error) {
+ var groups []*SeminarGroup
+ err := app.RecordQuery("groups").All(&groups)
if err != nil {
- slog.Error("Error while getting groups from database: ", "error", err)
return nil, err
}
var courseArray []string
-
- for _, course := range courses {
- courseArray = append(courseArray, course.CourseShortcut)
+ for _, g := range groups {
+ courseArray = append(courseArray, g.Course())
}
return courseArray, nil
}
-func FindCourseByCourseName(app *pocketbase.PocketBase, courseName string) (model.SeminarGroup, error) {
+func GetAllCoursesForSemester(app core.App, semester string) ([]model.SeminarGroup, error) {
+ var groups []*SeminarGroup
+ err := app.RecordQuery("groups").
+ AndWhere(dbx.NewExp("semester = {:semester}", dbx.Params{"semester": semester})).
+ All(&groups)
- var course SeminarGroup
-
- // get the course by its name
- err := app.Dao().DB().Select("*").From("groups").Where(dbx.NewExp("course = {:course}", dbx.Params{"course": courseName})).One(&course)
if err != nil {
- slog.Error("Error while getting group from database: ", "error", err)
- return model.SeminarGroup{}, err
+ return nil, err
}
- return course.toSeminarGroupModel(), nil
+ var models []model.SeminarGroup
+ for _, g := range groups {
+ models = append(models, g.ToModel())
+ }
+ return models, nil
+}
+
+func GetAllCoursesForSemesterWithEvents(app core.App, semester string) ([]string, error) {
+ var results []struct {
+ Course string `db:"course"`
+ }
+
+ err := app.DB().NewQuery(`
+ SELECT DISTINCT course FROM events WHERE semester = {:semester}
+ `).Bind(dbx.Params{"semester": semester}).All(&results)
+
+ if err != nil {
+ return nil, err
+ }
+
+ var courses []string
+ for _, r := range results {
+ courses = append(courses, r.Course)
+ }
+
+ return courses, nil
+}
+
+func SaveGroups(app core.App, seminarGroups []model.SeminarGroup) (model.SeminarGroups, error) {
+ // Delete all existing
+ execute, err := app.DB().Delete("groups", dbx.NewExp("1 = 1")).Execute()
+ if err != nil {
+ return nil, err
+ }
+ // Check if to delete was successful
+ rowCount, _ := execute.RowsAffected()
+
+ // Gruppen-Collection abrufen
+ collection, err := app.FindCollectionByNameOrId("groups")
+ if err != nil {
+ return nil, err
+ }
+
+ // Seminargruppen in die Datenbank speichern
+ savedGroups := SeminarGroups{}
+ for _, group := range seminarGroups {
+
+ dbSeminarGroup, recordErr := NewSeminarGroup(collection, group)
+ if recordErr != nil {
+ return nil, err
+ }
+
+ saveErr := app.Save(dbSeminarGroup)
+ if saveErr != nil {
+ return nil, saveErr
+ }
+ savedGroups = append(savedGroups, dbSeminarGroup)
+ }
+ slog.Info("Saved all groups to the database", "insert", len(savedGroups), "deleted", rowCount)
+
+ return savedGroups.ToModelArray(), nil
+
}
diff --git a/services/data-manager/service/db/dbRooms.go b/services/data-manager/service/db/dbRooms.go
index db97e57..dc1e9fd 100644
--- a/services/data-manager/service/db/dbRooms.go
+++ b/services/data-manager/service/db/dbRooms.go
@@ -34,7 +34,7 @@ func GetRooms(app *pocketbase.PocketBase) ([]string, error) {
}
// get all rooms from event records in the events collection
- err := app.Dao().DB().Select("Rooms", "course").From("events").Distinct(true).All(&events)
+ err := app.DB().Select("Rooms", "course").From("events").Distinct(true).All(&events)
if err != nil {
return nil, err
}
@@ -83,7 +83,7 @@ func GetRoomScheduleForDay(app *pocketbase.PocketBase, room string, date string)
var events []model.Event
// get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").
+ err := app.DB().Select("*").From("events").
Where(dbx.Like("Rooms", room).Escape("_", "_")).
AndWhere(dbx.Like("Start", date)).
GroupBy("Week", "Start", "End", "Rooms").
@@ -94,6 +94,21 @@ func GetRoomScheduleForDay(app *pocketbase.PocketBase, room string, date string)
return events, nil
}
+func GetRoomSchedule(app *pocketbase.PocketBase, room string) ([]model.Event, error) {
+ var events []model.Event
+
+ // get all events from event records in the events collection
+ err := app.DB().Select("*").From("events").
+ Where(dbx.Like("Rooms", room).Escape("_", "_")).
+ GroupBy("Week", "Start", "End", "Rooms").
+ All(&events)
+ if err != nil {
+ return nil, err
+ }
+ return events, nil
+
+}
+
func GetRoomScheduleInTimeSpan(app *pocketbase.PocketBase, room string, from string, to string) ([]model.Event, error) {
var events []model.Event
@@ -107,7 +122,7 @@ func GetRoomScheduleInTimeSpan(app *pocketbase.PocketBase, room string, from str
}
// get all events from event records in the events collection
- err = app.Dao().DB().Select("*").From("events").
+ err = app.DB().Select("*").From("events").
Where(dbx.Like("Rooms", room).Escape("_", "_")).
AndWhere(dbx.Between("Start", fromDate, toDate)).
GroupBy("Week", "Start", "End", "Rooms").
@@ -118,17 +133,3 @@ func GetRoomScheduleInTimeSpan(app *pocketbase.PocketBase, room string, from str
}
return events, nil
}
-
-func GetRoomSchedule(app *pocketbase.PocketBase, room string) ([]model.Event, error) {
- var events []model.Event
-
- // get all events from event records in the events collection
- err := app.Dao().DB().Select("*").From("events").
- Where(dbx.Like("Rooms", room).Escape("_", "_")).
- GroupBy("Week", "Start", "End", "Rooms").
- All(&events)
- if err != nil {
- return nil, err
- }
- return events, nil
-}
diff --git a/services/data-manager/service/db/dbFeeds_test.go b/services/data-manager/service/db/test/dbFeeds_test.go
similarity index 56%
rename from services/data-manager/service/db/dbFeeds_test.go
rename to services/data-manager/service/db/test/dbFeeds_test.go
index c7e29fc..bbd6d3f 100644
--- a/services/data-manager/service/db/dbFeeds_test.go
+++ b/services/data-manager/service/db/test/dbFeeds_test.go
@@ -14,58 +14,48 @@
//You should have received a copy of the GNU Affero General Public License
//along with this program. If not, see .
-package db
+package test
import (
- "github.com/pocketbase/pocketbase/daos"
+ "github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/tests"
+ "htwkalender/data-manager/model/serviceModel"
+ "htwkalender/data-manager/service"
+ "net/http"
"testing"
)
-const testDataDir = "./mockData"
+const testDataDir = "../mockData"
func TestDeleteFeed(t *testing.T) {
- setupTestApp := func(t *testing.T) *daos.Dao {
+ setupTestApp := func(t testing.TB) *tests.TestApp {
testApp, err := tests.NewTestApp(testDataDir)
if err != nil {
t.Fatal(err)
}
- dao := daos.New(testApp.Dao().DB())
- return dao
+
+ base := &pocketbase.PocketBase{App: testApp}
+
+ services := serviceModel.Service{App: base}
+
+ service.AddRoutes(services)
+
+ return testApp
}
- type args struct {
- db *daos.Dao
- feedId string
- }
- testsCases := []struct {
- name string
- args args
- wantErr bool
- }{
+ scenarios := []tests.ApiScenario{
{
- name: "TestDeleteFeed",
- args: args{
- db: setupTestApp(t),
- feedId: "fkoqti06ohlnsb8",
- },
- wantErr: false,
- },
- {
- name: "TestDeleteFeedNotExisting",
- args: args{
- db: setupTestApp(t),
- feedId: "test324",
- },
- wantErr: true,
+ Name: "TestDeleteFeed",
+ Method: "DELETE",
+ URL: "/api/v1/feeds/fkoqti06ohlnsb8",
+ ExpectedStatus: http.StatusNotFound,
+ ExpectedContent: []string{"\"data\":{},\"message\":\"The requested resource wasn't found.\",\"status\":404"},
+ TestAppFactory: setupTestApp,
},
}
- for _, tt := range testsCases {
- t.Run(tt.name, func(t *testing.T) {
- if err := DeleteFeed(tt.args.db, tt.args.feedId); (err != nil) != tt.wantErr {
- t.Errorf("DeleteFeed() error = %v, wantErr %v", err, tt.wantErr)
- }
- })
+
+ for _, scenario := range scenarios {
+ scenario.Test(t)
}
}
diff --git a/services/data-manager/service/events/courseService.go b/services/data-manager/service/events/courseService.go
index 3bf460e..2b81a0c 100644
--- a/services/data-manager/service/events/courseService.go
+++ b/services/data-manager/service/events/courseService.go
@@ -21,6 +21,7 @@ import (
"htwkalender/data-manager/model"
"htwkalender/data-manager/service/db"
"htwkalender/data-manager/service/functions"
+ "log/slog"
)
// CourseService defines the methods to be implemented
@@ -43,12 +44,23 @@ func NewPocketBaseCourseService(app *pocketbase.PocketBase) *PocketBaseCourseSer
// GetAllCourses returns all courses
func (s *PocketBaseCourseService) GetAllCourses() []string {
- return db.GetAllCourses(s.app)
+ courseList, err := db.GetAllCourses(s.app)
+ if err != nil {
+ slog.Error("Could not get all courses", "error", err)
+ return nil
+ }
+
+ return courseList
}
// GetAllCoursesForSemester returns all courses for a specific semester
func (s *PocketBaseCourseService) GetAllCoursesForSemester(semester string) []model.SeminarGroup {
- return db.GetAllCoursesForSemester(s.app, semester)
+ seminarGroups, err := db.GetAllCoursesForSemester(s.app, semester)
+ if err != nil {
+ slog.Error("Could not get all courses for semester", "error", err)
+ return nil
+ }
+ return seminarGroups
}
// GetAllCoursesForSemesterWithEvents returns all courses for a specific semester with events
diff --git a/services/data-manager/service/events/eventService.go b/services/data-manager/service/events/eventService.go
index 2a3c756..12d4338 100644
--- a/services/data-manager/service/events/eventService.go
+++ b/services/data-manager/service/events/eventService.go
@@ -112,7 +112,7 @@ func (s *PocketBaseEventService) GetModuleByUUID(uuid string) (model.Module, err
// If the deletion was successful, nil is returned
// If the deletion was not successful, an error is returned
func (s *PocketBaseEventService) DeleteAllEventsByCourseAndSemester(course string, semester string) error {
- err := db.DeleteAllEventsByCourse(s.app.Dao(), course, semester)
+ err := db.DeleteAllEventsByCourse(s.app, course, semester)
if err != nil {
return err
} else {
@@ -151,7 +151,7 @@ func (s *PocketBaseEventService) UpdateModulesForCourse(seminarGroup model.Semin
//if there are no events in the database, save the new events
//get all events for the course and the semester
- dbEvents, err := db.GetAllEventsForCourseAndSemester(s.app, seminarGroup.Course, seminarGroup.Semester)
+ dbEvents, err := db.GetAllEventsForCourse(s.app, seminarGroup.Course)
if err != nil {
return nil, err
}
@@ -191,13 +191,13 @@ func (s *PocketBaseEventService) UpdateModulesForCourse(seminarGroup model.Semin
}
// save all events that are in the insertList
- savedEvents, err := db.SaveEvents(insertList, s.app.Dao())
+ savedEvents, err := db.SaveEvents(insertList, s.app)
if err != nil {
slog.Error("Failed to save events: ", "error", err)
return nil, err
}
- slog.Info("Course: " + seminarGroup.Course + " [" + seminarGroup.Semester + "] - Events: " + strconv.FormatInt(int64(len(savedEvents)), 10) + " new, " + strconv.FormatInt(int64(len(deleteList)), 10) + " deleted" + ", " + strconv.FormatInt(int64(len(dbEvents)-len(deleteList)+len(savedEvents)), 10) + " total")
+ slog.Info("Course: " + seminarGroup.Course + " - Event changes: " + strconv.FormatInt(int64(len(insertList)), 10) + " new events, " + strconv.FormatInt(int64(len(deleteList)), 10) + " deleted events")
return savedEvents, nil
}
diff --git a/services/data-manager/service/feed/feedFunctions.go b/services/data-manager/service/feed/feedFunctions.go
index 6c16c7e..a891d0a 100644
--- a/services/data-manager/service/feed/feedFunctions.go
+++ b/services/data-manager/service/feed/feedFunctions.go
@@ -17,7 +17,7 @@
package feed
import (
- "github.com/pocketbase/pocketbase/daos"
+ "github.com/pocketbase/pocketbase"
"htwkalender/data-manager/model"
database "htwkalender/data-manager/service/db"
localTime "htwkalender/data-manager/service/functions/time"
@@ -25,8 +25,8 @@ import (
"strings"
)
-func ClearFeeds(db *daos.Dao, months int, clock localTime.Clock) {
- feeds, err := database.GetAllFeeds(db)
+func ClearFeeds(base *pocketbase.PocketBase, months int, clock localTime.Clock) {
+ feeds, err := database.GetAllFeeds(base)
if err != nil {
slog.Error("CleanFeeds: failed to get all feeds", "error", err)
return
@@ -39,9 +39,9 @@ func ClearFeeds(db *daos.Dao, months int, clock localTime.Clock) {
if feedRetrievedTime.Before(timeShift) {
// delete feed
- feedErr := database.DeleteFeed(db, feed.GetId())
+ feedErr := database.DeleteFeed(base, feed.Id)
if feedErr != nil {
- slog.Error("CleanFeeds: failed to delete feed: "+feed.GetId(), "error", feedErr)
+ slog.Error("CleanFeeds: failed to delete feed: "+feed.Id, "error", feedErr)
}
}
}
@@ -119,6 +119,6 @@ func combineRooms(events model.Events, index1 int, combinedEvents model.Events,
return combinedEvents[index2].Rooms
}
-func MarkFeedForDeletion(db *daos.Dao, feedId string) error {
- return database.MarkForDelete(db, feedId)
+func MarkFeedForDeletion(base *pocketbase.PocketBase, feedId string) error {
+ return database.MarkForDelete(base, feedId)
}
diff --git a/services/data-manager/service/feed/feedFunctions_test.go b/services/data-manager/service/feed/test/feedFunctions_test.go
similarity index 84%
rename from services/data-manager/service/feed/feedFunctions_test.go
rename to services/data-manager/service/feed/test/feedFunctions_test.go
index 53286ba..240d264 100644
--- a/services/data-manager/service/feed/feedFunctions_test.go
+++ b/services/data-manager/service/feed/test/feedFunctions_test.go
@@ -14,45 +14,43 @@
//You should have received a copy of the GNU Affero General Public License
//along with this program. If not, see .
-package feed
+package test
import (
- "github.com/pocketbase/pocketbase/daos"
+ "github.com/pocketbase/pocketbase"
"github.com/pocketbase/pocketbase/tests"
"htwkalender/data-manager/model"
+ "htwkalender/data-manager/service/feed"
mockTime "htwkalender/data-manager/service/functions/time"
"reflect"
"testing"
"time"
)
-const testDataDir = "./mockData"
+const testDataDir = "../mockData"
+
+func setupTestApp(t testing.TB) *tests.TestApp {
+ testApp, err := tests.NewTestApp(testDataDir)
+ if err != nil {
+ t.Fatal(err)
+ }
+ return testApp
+}
func TestClearFeeds(t *testing.T) {
-
- setupTestApp := func(t *testing.T) *daos.Dao {
- testApp, err := tests.NewTestApp(testDataDir)
- if err != nil {
- t.Fatal(err)
- }
- dao := daos.New(testApp.Dao().DB())
- return dao
- }
-
type args struct {
- db *daos.Dao
months int
mockClock mockTime.MockClock
}
+
testCases := []struct {
name string
args args
want int
}{
{
- name: "TestClearFeeds",
+ name: "Clear feeds older than 6 months",
args: args{
- db: setupTestApp(t),
months: 6,
mockClock: mockTime.MockClock{
NowTime: time.Date(2023, 12, 1, 0, 0, 0, 0, time.UTC),
@@ -61,9 +59,8 @@ func TestClearFeeds(t *testing.T) {
want: 1,
},
{
- name: "TestClearAllFeeds",
+ name: "Clear all feeds - recent clock",
args: args{
- db: setupTestApp(t),
months: 1,
mockClock: mockTime.MockClock{
NowTime: time.Date(2024, 1, 1, 0, 0, 0, 0, time.UTC),
@@ -72,9 +69,8 @@ func TestClearFeeds(t *testing.T) {
want: 0,
},
{
- name: "TestClearFeedsClearBeforeRetrievedTime",
+ name: "No clearing - very old clock",
args: args{
- db: setupTestApp(t),
months: 1,
mockClock: mockTime.MockClock{
NowTime: time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC),
@@ -83,15 +79,20 @@ func TestClearFeeds(t *testing.T) {
want: 3,
},
}
+
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
- ClearFeeds(tt.args.db, tt.args.months, tt.args.mockClock)
- // count all feeds in db
+ app := setupTestApp(t)
+ base := &pocketbase.PocketBase{App: app}
+
+ feed.ClearFeeds(base, tt.args.months, tt.args.mockClock)
+
var feeds []*model.Feed
- err := tt.args.db.DB().Select("id").From("feeds").All(&feeds)
+ err := app.DB().Select("id").From("feeds").All(&feeds)
if err != nil {
t.Fatal(err)
}
+
if got := len(feeds); got != tt.want {
t.Errorf("ClearFeeds() = %v, want %v", got, tt.want)
}
@@ -109,7 +110,7 @@ func TestCombineEventsInFeed(t *testing.T) {
want model.Events
}{
{
- name: "TestCombineEventsInFeed",
+ name: "Combine duplicate events with different rooms and notes",
args: args{
events: model.Events{
{
@@ -142,7 +143,7 @@ func TestCombineEventsInFeed(t *testing.T) {
},
},
{
- name: "CannotCombineEventsInFeed",
+ name: "Do not combine different events",
args: args{
events: model.Events{
{
@@ -183,16 +184,17 @@ func TestCombineEventsInFeed(t *testing.T) {
},
},
{
- name: "NoEventsInFeed",
+ name: "Empty events input",
args: args{
events: model.Events{},
},
want: model.Events{},
},
}
+
for _, tt := range testCases {
t.Run(tt.name, func(t *testing.T) {
- if got := CombineEventsInFeed(tt.args.events); !reflect.DeepEqual(got, tt.want) {
+ if got := feed.CombineEventsInFeed(tt.args.events); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CombineEventsInFeed() = %v, want %v", got, tt.want)
}
})
diff --git a/services/data-manager/service/fetch/sport/sportFetcher.go b/services/data-manager/service/fetch/sport/sportFetcher.go
index 93ecdfc..4e29ea0 100644
--- a/services/data-manager/service/fetch/sport/sportFetcher.go
+++ b/services/data-manager/service/fetch/sport/sportFetcher.go
@@ -82,13 +82,13 @@ func FetchAndUpdateSportEvents(app *pocketbase.PocketBase) ([]model.Event, error
}
// @TODO: delete and save events in one transaction and it only should delete events that are not in the new events list and save events that are not in the database
- err = db.DeleteAllEventsByCourse(app.Dao(), "Sport", functions.GetCurrentSemesterString(clock.RealClock{}))
+ err = db.DeleteAllEventsByCourse(app, "Sport", functions.GetCurrentSemesterString(clock.RealClock{}))
if err != nil {
return nil, err
}
// save events to database
- savedEvents, err := db.SaveEvents(events, app.Dao())
+ savedEvents, err := db.SaveEvents(events, app)
if err != nil {
return nil, err
diff --git a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go
index 692847c..8672a61 100644
--- a/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go
+++ b/services/data-manager/service/fetch/v1/fetchSeminarGroupService.go
@@ -57,8 +57,8 @@ func getSeminarHTML(semester string) (string, error) {
}
-func FetchSeminarGroups(app *pocketbase.PocketBase) (db.SeminarGroups, error) {
- var groups db.SeminarGroups
+func FetchSeminarGroups(base *pocketbase.PocketBase) (model.SeminarGroups, error) {
+ var groups model.SeminarGroups
semesterString := functions.CalculateSemesterList(time.RealClock{})
var results [2]string
@@ -76,7 +76,7 @@ func FetchSeminarGroups(app *pocketbase.PocketBase) (db.SeminarGroups, error) {
// filter duplicates
groups = removeDuplicates(groups)
- insertedGroups, dbError := db.SaveGroups(groups, app)
+ insertedGroups, dbError := db.SaveGroups(base.App, groups)
if dbError != nil {
slog.Error("FetchSeminarGroups", "error", dbError)
return nil, err
@@ -85,8 +85,8 @@ func FetchSeminarGroups(app *pocketbase.PocketBase) (db.SeminarGroups, error) {
return insertedGroups, nil
}
-func removeDuplicates(groups db.SeminarGroups) db.SeminarGroups {
- uniqueGroups := make(db.SeminarGroups, 0, len(groups))
+func removeDuplicates(groups model.SeminarGroups) model.SeminarGroups {
+ uniqueGroups := make(model.SeminarGroups, 0, len(groups))
seen := make(map[string]struct{}) // Use an empty struct to minimize memory usage
// unique Identifier is the course and semester
@@ -109,7 +109,7 @@ func contains(groups []model.SeminarGroup, group model.SeminarGroup) bool {
return false
}
-func parseSeminarGroups(result string, semester string) db.SeminarGroups {
+func parseSeminarGroups(result string, semester string) model.SeminarGroups {
var studium model.Studium
err := xml.Unmarshal([]byte(result), &studium)
@@ -117,11 +117,11 @@ func parseSeminarGroups(result string, semester string) db.SeminarGroups {
return nil
}
- var seminarGroups db.SeminarGroups
+ var seminarGroups model.SeminarGroups
for _, faculty := range studium.Faculty {
for _, Studiengang := range faculty.Studiengang {
for _, Studienrichtung := range Studiengang.Semgrp {
- seminarGroup := db.SeminarGroup{
+ seminarGroup := model.SeminarGroup{
University: "HTWK-Leipzig",
GroupShortcut: Studiengang.Name,
GroupId: Studiengang.ID,
@@ -130,7 +130,7 @@ func parseSeminarGroups(result string, semester string) db.SeminarGroups {
FacultyId: faculty.ID,
Semester: semester,
}
- seminarGroups = append(seminarGroups, &seminarGroup)
+ seminarGroups = append(seminarGroups, seminarGroup)
}
}
}
diff --git a/services/data-manager/service/fetch/v2/fetcher.go b/services/data-manager/service/fetch/v2/fetcher.go
index ed1e77a..877d963 100644
--- a/services/data-manager/service/fetch/v2/fetcher.go
+++ b/services/data-manager/service/fetch/v2/fetcher.go
@@ -20,7 +20,7 @@ import (
"fmt"
"github.com/google/uuid"
"github.com/pocketbase/pocketbase"
- "github.com/pocketbase/pocketbase/daos"
+ "github.com/pocketbase/pocketbase/core"
"golang.org/x/net/html"
"htwkalender/data-manager/model"
"htwkalender/data-manager/service/db"
@@ -100,19 +100,19 @@ func fetchAndSaveAllEventsForSemester(
return savedRecords, err
}
-func updateDatabase(app *pocketbase.PocketBase, eventsToBeAdded []model.Event, course string, semester string) error {
+func updateDatabase(base *pocketbase.PocketBase, eventsToBeAdded []model.Event, course string, semester string) error {
var addedEvents []model.Event
var err error
// to in transaction the events will be added and deleted
- err = app.Dao().RunInTransaction(func(txDao *daos.Dao) error {
- err = db.DeleteAllEventsRatherThenCourse(txDao, course, semester)
+ err = base.RunInTransaction(func(app core.App) error {
+ err = db.DeleteAllEventsRatherThenCourse(app, course, semester)
if err != nil {
return err
}
- addedEvents, err = db.SaveEvents(eventsToBeAdded, txDao)
+ addedEvents, err = db.SaveEvents(eventsToBeAdded, app)
if err != nil {
return err
}
diff --git a/services/data-manager/service/ical/ical.go b/services/data-manager/service/ical/ical.go
index 9711f11..d99e66b 100644
--- a/services/data-manager/service/ical/ical.go
+++ b/services/data-manager/service/ical/ical.go
@@ -24,24 +24,17 @@ import (
"htwkalender/data-manager/service/db"
)
-func CreateIndividualFeed(requestBody []byte, app *pocketbase.PocketBase) (string, error) {
- var modules []model.FeedCollection
-
- err := json.Unmarshal(requestBody, &modules)
- if err != nil {
- return "", apis.NewNotFoundError("Could not parse request body", err)
- }
-
+func CreateIndividualFeed(modules []model.FeedCollection, pb *pocketbase.PocketBase) (string, error) {
var icalFeed model.Feed
jsonModules, _ := json.Marshal(modules)
icalFeed.Modules = string(jsonModules)
- collection, dbError := db.FindCollection(app, "feeds")
+ collection, dbError := pb.FindCollectionByNameOrId("feeds")
if dbError != nil {
return "", apis.NewNotFoundError("Collection could not be found", dbError)
}
- record, err := db.SaveFeed(icalFeed, collection, app)
+ record, err := db.SaveFeed(icalFeed, collection, pb)
if err != nil {
return "", apis.NewNotFoundError("Could not save feed", err)
}
diff --git a/services/go.mod b/services/go.mod
index 1ed6d25..c8ed356 100644
--- a/services/go.mod
+++ b/services/go.mod
@@ -14,9 +14,9 @@ require (
github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0
github.com/labstack/echo/v5 v5.0.0-20230722203903-ec5b858dab61
github.com/pocketbase/dbx v1.11.0
- github.com/pocketbase/pocketbase v0.22.29
+ github.com/pocketbase/pocketbase v0.27.1
github.com/stretchr/testify v1.10.0
- golang.org/x/net v0.37.0
+ golang.org/x/net v0.39.0
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
)
@@ -47,17 +47,25 @@ require (
github.com/aws/smithy-go v1.22.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/disintegration/imaging v1.6.3-0.20201218193011-d40f48ce0f09 // indirect
+ github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
+ github.com/dop251/base64dec v0.0.0-20231022112746-c6c9f9a96217 // indirect
+ github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c // indirect
+ github.com/dop251/goja_nodejs v0.0.0-20250314160716-c55ecee183c0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/color v1.18.0 // indirect
+ github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
- github.com/ganigeorgiev/fexpr v0.4.1 // indirect
+ github.com/ganigeorgiev/fexpr v0.5.0 // indirect
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
+ github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
github.com/gofiber/schema v1.3.0 // indirect
github.com/gofiber/utils/v2 v2.0.0-beta.7 // indirect
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
+ github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect
+ github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e // indirect
github.com/googleapis/gax-go/v2 v2.14.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
@@ -69,34 +77,36 @@ require (
github.com/ncruces/go-strftime v0.1.9 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
+ github.com/pocketbase/tygoja v0.0.0-20250103200817-ca580d8c5119 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/spf13/cast v1.7.1 // indirect
- github.com/spf13/cobra v1.8.1 // indirect
- github.com/spf13/pflag v1.0.5 // indirect
+ github.com/spf13/cobra v1.9.1 // indirect
+ github.com/spf13/pflag v1.0.6 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/tinylib/msgp v1.2.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.59.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
- github.com/valyala/tcplisten v1.0.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.opencensus.io v0.24.0 // indirect
gocloud.dev v0.40.0 // indirect
- golang.org/x/crypto v0.36.0 // indirect
- golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
- golang.org/x/image v0.23.0 // indirect
- golang.org/x/oauth2 v0.28.0 // indirect
- golang.org/x/sync v0.12.0 // indirect
- golang.org/x/sys v0.31.0 // indirect
- golang.org/x/term v0.30.0 // indirect
- golang.org/x/text v0.23.0 // indirect
+ golang.org/x/crypto v0.37.0 // indirect
+ golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
+ golang.org/x/image v0.26.0 // indirect
+ golang.org/x/mod v0.24.0 // indirect
+ golang.org/x/oauth2 v0.29.0 // indirect
+ golang.org/x/sync v0.13.0 // indirect
+ golang.org/x/sys v0.32.0 // indirect
+ golang.org/x/term v0.31.0 // indirect
+ golang.org/x/text v0.24.0 // indirect
golang.org/x/time v0.11.0 // indirect
+ golang.org/x/tools v0.32.0 // indirect
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect
google.golang.org/api v0.225.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
- modernc.org/libc v1.61.13 // indirect
+ modernc.org/libc v1.62.1 // indirect
modernc.org/mathutil v1.7.1 // indirect
- modernc.org/memory v1.8.2 // indirect
- modernc.org/sqlite v1.36.0 // indirect
+ modernc.org/memory v1.9.1 // indirect
+ modernc.org/sqlite v1.37.0 // indirect
)
diff --git a/services/go.sum b/services/go.sum
index ddf28ed..d9be54e 100644
--- a/services/go.sum
+++ b/services/go.sum
@@ -3,8 +3,6 @@ cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.115.0 h1:CnFSK6Xo3lDYRoBKEcAtia6VSC837/ZkJuRduSFnr14=
cloud.google.com/go v0.115.0/go.mod h1:8jIM5vVgoAEoiVxQ/O4BFTfHqulPZgs/ufEzMcFMdWU=
-cloud.google.com/go/auth v0.14.0 h1:A5C4dKV/Spdvxcl0ggWwWEzzP7AZMJSEIgrkngwhGYM=
-cloud.google.com/go/auth v0.14.0/go.mod h1:CYsoRL1PdiDuqeQpZE0bP2pnPrGqFcOkI0nldEQis+A=
cloud.google.com/go/auth v0.15.0 h1:Ly0u4aA5vG/fsSsxu98qCQBemXtAtJf+95z9HK+cxps=
cloud.google.com/go/auth v0.15.0/go.mod h1:WJDGqZ1o9E9wKIL+IwStfyn/+s59zl4Bi+1KQNVXLZ8=
cloud.google.com/go/auth/oauth2adapt v0.2.7 h1:/Lc7xODdqcEw8IrZ9SvwnlLX6j9FHQM74z6cBk9Rw6M=
@@ -69,18 +67,16 @@ github.com/GoogleCloudPlatform/cloudsql-proxy v1.36.0 h1:kAtNAWwvTt5+iew6baV0kbO
github.com/GoogleCloudPlatform/cloudsql-proxy v1.36.0/go.mod h1:VRKXU8C7Y/aUKjRBTGfw0Ndv4YqNxlB8zAPJJDxbASE=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 h1:3c8yed4lgqTt+oTQ+JNMDo+F4xprBf+O/il4ZC0nRLw=
github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0/go.mod h1:obipzmGjfSjam60XLwGfqUkJsfiheAl+TUjG+4yzyPM=
+github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0=
+github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
-github.com/PuerkitoBio/goquery v1.10.1 h1:Y8JGYUkXWTGRB6Ars3+j3kN0xg1YqqlwvdTV8WTFQcU=
-github.com/PuerkitoBio/goquery v1.10.1/go.mod h1:IYiHrOMps66ag56LEH7QYDDupKXyo5A8qrjIx3ZtujY=
github.com/PuerkitoBio/goquery v1.10.2 h1:7fh2BdHcG6VFZsK7toXBT/Bh1z5Wmy8Q9MV9HqT2AM8=
github.com/PuerkitoBio/goquery v1.10.2/go.mod h1:0guWGjcLu9AYC7C1GHnpysHy056u9aEkUHwhdnePMCU=
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM=
github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA=
-github.com/arran4/golang-ical v0.3.2-0.20241015053101-5bb438cf85f5 h1:aIT5x2Cjcg/bioaV8mc1jpDOiousU0alvWTNIcX+F5E=
-github.com/arran4/golang-ical v0.3.2-0.20241015053101-5bb438cf85f5/go.mod h1:xblDGxxIUMWwFZk9dlECUlc1iXNV65LJZOTHLVwu8bo=
github.com/arran4/golang-ical v0.3.2 h1:MGNjcXJFSuCXmYX/RpZhR2HDCYoFuK8vTPFLEdFC3JY=
github.com/arran4/golang-ical v0.3.2/go.mod h1:xblDGxxIUMWwFZk9dlECUlc1iXNV65LJZOTHLVwu8bo=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
@@ -141,14 +137,17 @@ github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMr
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
+github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI=
+github.com/chzyer/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3 h1:boJj011Hh+874zpIySeApCX4GeOjPl9qhRF3QuIZq+Q=
github.com/cncf/xds/go v0.0.0-20241223141626-cff3c89139a3/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8=
-github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.6 h1:XJtiaUW6dEEqVuZiMTn1ldk455QWwEIsMIJlo5vtkx0=
+github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/creack/pty v1.1.17 h1:QeVUsEDNrLBW4tMgZHvxy18sKtr6VI492kBhUfhDJNI=
github.com/creack/pty v1.1.17/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -156,14 +155,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/imaging v1.6.3-0.20201218193011-d40f48ce0f09 h1:MJFqtdxTq94XqUgg7DcGCaOIXrDTJE/tPHK66Jshguc=
github.com/disintegration/imaging v1.6.3-0.20201218193011-d40f48ce0f09/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
-github.com/dlclark/regexp2 v1.11.4 h1:rPYF9/LECdNymJufQKmri9gV604RvvABwgOA8un7yAo=
-github.com/dlclark/regexp2 v1.11.4/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
+github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
+github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCOBXMn8=
github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
-github.com/dop251/goja v0.0.0-20241009100908-5f46f2705ca3 h1:MXsAuToxwsTn5BEEYm2DheqIiC4jWGmkEJ1uy+KFhvQ=
-github.com/dop251/goja v0.0.0-20241009100908-5f46f2705ca3/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
-github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc h1:MKYt39yZJi0Z9xEeRmDX2L4ocE0ETKcHKw6MVL3R+co=
-github.com/dop251/goja_nodejs v0.0.0-20240728170619-29b559befffc/go.mod h1:VULptt4Q/fNzQUJlqY/GP3qHyU7ZH46mFkBZe0ZTokU=
+github.com/dop251/base64dec v0.0.0-20231022112746-c6c9f9a96217 h1:16iT9CBDOniJwFGPI41MbUDfEk74hFaKTqudrX8kenY=
+github.com/dop251/base64dec v0.0.0-20231022112746-c6c9f9a96217/go.mod h1:eIb+f24U+eWQCIsj9D/ah+MD9UP+wdxuqzsdLD+mhGM=
+github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c h1:mxWGS0YyquJ/ikZOjSrRjjFIbUqIP9ojyYQ+QZTU3Rg=
+github.com/dop251/goja v0.0.0-20250309171923-bcd7cc6bf64c/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
+github.com/dop251/goja_nodejs v0.0.0-20250314160716-c55ecee183c0 h1:jTwdYTGERaZ/3+glBUVQZV2NwGodd9HlkXJbTBUPLLo=
+github.com/dop251/goja_nodejs v0.0.0-20250314160716-c55ecee183c0/go.mod h1:Tb7Xxye4LX7cT3i8YLvmPMGCV92IOi4CDZvm/V8ylc0=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -192,6 +193,8 @@ github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3G
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
github.com/ganigeorgiev/fexpr v0.4.1 h1:hpUgbUEEWIZhSDBtf4M9aUNfQQ0BZkGRaMePy7Gcx5k=
github.com/ganigeorgiev/fexpr v0.4.1/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
+github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
+github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
@@ -204,22 +207,18 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
-github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
-github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofiber/fiber/v3 v3.0.0-beta.4 h1:KzDSavvhG7m81NIsmnu5l3ZDbVS4feCidl4xlIfu6V0=
github.com/gofiber/fiber/v3 v3.0.0-beta.4/go.mod h1:/WFUoHRkZEsGHyy2+fYcdqi109IVOFbVwxv1n1RU+kk=
-github.com/gofiber/schema v1.2.0 h1:j+ZRrNnUa/0ZuWrn/6kAtAufEr4jCJ+JuTURAMxNSZg=
-github.com/gofiber/schema v1.2.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
github.com/gofiber/schema v1.3.0 h1:K3F3wYzAY+aivfCCEHPufCthu5/13r/lzp1nuk6mr3Q=
github.com/gofiber/schema v1.3.0/go.mod h1:YYwj01w3hVfaNjhtJzaqetymL56VW642YS3qZPhuE6c=
github.com/gofiber/utils/v2 v2.0.0-beta.7 h1:NnHFrRHvhrufPABdWajcKZejz9HnCWmT/asoxRsiEbQ=
github.com/gofiber/utils/v2 v2.0.0-beta.7/go.mod h1:J/M03s+HMdZdvhAeyh76xT72IfVqBzuz/OJkrMa7cwU=
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
-github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk=
-github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
+github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8=
+github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc=
github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w=
@@ -246,7 +245,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
@@ -258,6 +256,8 @@ github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9
github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5 h1:5iH8iuqE5apketRbSFBy+X1V0o+l+8NF1avt4HWl7cA=
github.com/google/pprof v0.0.0-20240827171923-fa2c70bbbfe5/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
+github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
+github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/s2a-go v0.1.9 h1:LGD7gtMgezd8a/Xak7mEWL0PjoTQFvpRudN895yqKW0=
github.com/google/s2a-go v0.1.9/go.mod h1:YA0Ei2ZQL3acow2O62kdp9UlnvMmU7kA6Eutn0dXayM=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -265,18 +265,16 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/wire v0.6.0 h1:HBkoIh4BdSxoyo9PveV8giw7ZsaBOvzWKfcg/6MrVwI=
github.com/google/wire v0.6.0/go.mod h1:F4QhpQ9EDIdJ1Mbop/NZBRB+5yrR6qg3BnctaoUk6NA=
-github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gTgghdIA6Stxb52D5RnLI1SLyw=
-github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA=
github.com/googleapis/enterprise-certificate-proxy v0.3.5 h1:VgzTY2jogw3xt39CusEnFJWm7rlsq5yL5q9XdLOuP5g=
github.com/googleapis/enterprise-certificate-proxy v0.3.5/go.mod h1:MkHOF77EYAE7qfSuSS9PU6g4Nt4e11cnsDUowfwewLA=
github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrkurSS/Q=
github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
-github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
+github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE=
+github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.3.1 h1:iUx3whfZWVf3jT01hQTO/Eo5sAYtB2/rqaUuOtpInww=
@@ -289,8 +287,6 @@ github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0 h1:p+k2RozdR141dIkAbO
github.com/jordic/goics v0.0.0-20210404174824-5a0337b716a0/go.mod h1:YHaw6sOIeFRob8Y9q/blEAMfVcLpeE9+vdhrwyEMxoI=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
-github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
-github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@@ -334,8 +330,10 @@ github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
github.com/pocketbase/pocketbase v0.22.29 h1:ii3+dfrKpmmybtr8hpRgjnQPiEnpBf7H5xW+4ygj4O4=
github.com/pocketbase/pocketbase v0.22.29/go.mod h1:GxrFIFusnUSkKPi4KoLz2jHkmMYhbfFqMyDlaqbAZ+U=
-github.com/pocketbase/tygoja v0.0.0-20241015175937-d6ff411a0f75 h1:XSbmekxgmbI2uPrre/nkCz7y8VsV652TPb3hAYzPb74=
-github.com/pocketbase/tygoja v0.0.0-20241015175937-d6ff411a0f75/go.mod h1:hKJWPGFqavk3cdTa47Qvs8g37lnfI57OYdVVbIqW5aE=
+github.com/pocketbase/pocketbase v0.27.1 h1:KGCsS8idUVTC5QHxTj91qHDhIXOb5Yb50wwHhNvJRTQ=
+github.com/pocketbase/pocketbase v0.27.1/go.mod h1:aTpwwloVJzeJ7MlwTRrbI/x62QNR2/kkCrovmyrXpqs=
+github.com/pocketbase/tygoja v0.0.0-20250103200817-ca580d8c5119 h1:TjQtEReJDTpvlNFTRjuHvPQpJHAeJdcQF130eCAAT/o=
+github.com/pocketbase/tygoja v0.0.0-20250103200817-ca580d8c5119/go.mod h1:hKJWPGFqavk3cdTa47Qvs8g37lnfI57OYdVVbIqW5aE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/prometheus v0.54.0 h1:6+VmEkohHcofl3W5LyRlhw1Lfm575w/aX6ZFyVAmzM0=
@@ -350,8 +348,12 @@ github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y=
github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
+github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
+github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
+github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
+github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -368,8 +370,6 @@ github.com/tinylib/msgp v1.2.5 h1:WeQg1whrXRFiZusidTQqzETkRpGjFjcIhW6uqWH09po=
github.com/tinylib/msgp v1.2.5/go.mod h1:ykjzy2wzgrlvpDCRc4LA8UXy6D8bzMSuAF3WD57Gok0=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
-github.com/valyala/fasthttp v1.58.0 h1:GGB2dWxSbEprU9j0iMJHgdKYJVDyjrOwF9RE59PbRuE=
-github.com/valyala/fasthttp v1.58.0/go.mod h1:SYXvHHaFp7QZHGKSHmoMipInhrI5StHrhDTYVEjK/Kw=
github.com/valyala/fasthttp v1.59.0 h1:Qu0qYHfXvPk1mSLNqcFtEk6DpxgA26hy6bmydotDpRI=
github.com/valyala/fasthttp v1.59.0/go.mod h1:GTxNb9Bc6r2a9D0TWNSPwDz78UxnTGBViY3xZNEqyYU=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
@@ -388,34 +388,22 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao=
go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0 h1:r6I7RJCN86bpD/FQwedZ0vSixDpwuWREjW9oRMsmqDc=
-go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.54.0/go.mod h1:B9yO6b04uB80CzjedvewuqDhxJxi11s7/GtiGa8bAjI=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 h1:TT4fX+nBOA/+LUkobKGW1ydGcn+G3vRw9+g5HwCphpk=
-go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0/go.mod h1:L7UH0GbB0p47T4Rri3uHjbpCFYrVrwc1I25QhNPiGK8=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I=
-go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY=
-go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE=
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
-go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE=
-go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY=
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
-go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk=
-go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0=
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
-go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc=
-go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8=
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
-go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys=
-go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A=
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
@@ -429,16 +417,20 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
-golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
-golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
+golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE=
+golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA=
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
+golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 h1:R84qjqJb5nVJMxqWYb3np9L5ZsaDtB+a39EqjV0JSUM=
+golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0/go.mod h1:S9Xr4PYopiDyqSyp5NjCrhFrqg6A5zA2E/iPHPhqnS8=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
+golang.org/x/image v0.26.0 h1:4XjIFEZWQmCZi6Wv8BoxsDhRU3RVnLX04dToTDAEPlY=
+golang.org/x/image v0.26.0/go.mod h1:lcxbMFAovzpnJxzXS3nyL83K27tmqtKzIJpctK8YO5c=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
@@ -450,6 +442,8 @@ golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
+golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
+golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -466,15 +460,15 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
-golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
-golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
+golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY=
+golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
-golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
-golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
+golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
+golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -483,10 +477,11 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
-golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
+golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
+golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -503,12 +498,13 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
-golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
-golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2 h1:IRJeR9r1pYWsHKTRe/IInb7lYvbBVIqOgsX/u0mbOWY=
+golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
+golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
+golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk=
+golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -517,10 +513,10 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
-golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
-golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
+golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o=
+golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -531,12 +527,11 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
-golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
-golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
-golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
+golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0=
+golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU=
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -551,12 +546,12 @@ golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=
+golang.org/x/tools v0.32.0 h1:Q7N1vhpkQv7ybVzLFtTjvQya2ewbwNDZzUgfXGqtMWU=
+golang.org/x/tools v0.32.0/go.mod h1:ZxrU41P/wAbZD8EDa6dDCa6XfpkhJ7HFMjHJXfBDu8s=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
-google.golang.org/api v0.217.0 h1:GYrUtD289o4zl1AhiTZL0jvQGa2RDLyC+kX1N/lfGOU=
-google.golang.org/api v0.217.0/go.mod h1:qMc2E8cBAbQlRypBTBWHklNJlaZZJBwDv81B1Iu8oSI=
google.golang.org/api v0.225.0 h1:+4/IVqBQm0MV5S+JW3kdEGC1WtOmM2mXN1LKH1LdNlw=
google.golang.org/api v0.225.0/go.mod h1:WP/0Xm4LVvMOCldfvOISnWquSRWbG2kArDZcg+W2DbY=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
@@ -568,16 +563,10 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988 h1:CT2Thj5AuPV9phrYMtzX11k+XkzMGfRAet42PmoTATM=
google.golang.org/genproto v0.0.0-20240812133136-8ffd90a71988/go.mod h1:7uvplUBj4RjHAxIZ//98LzOvrQ04JBkaixRmCMI29hc=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q=
-google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08=
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20250303144028-a0af3efb3deb h1:kw/Q892zrnljh8PXAIHmsCXgpxtSyWL4oV1eRnFtdeg=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:35wIojE/F1ptq1nfNDNjtowabHoMSA2qQs7+smpCO5s=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf h1:dHDlF3CWxQkefK9IJx+O8ldY0gLygvrlYRBNbPqDWuY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250311190419-81fb87f6b8bf/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -585,8 +574,6 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
-google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A=
-google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -598,54 +585,52 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
-google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU=
-google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
+gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
-lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
-modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
-modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
-modernc.org/ccgo/v3 v3.17.0 h1:o3OmOqx4/OFnl4Vm3G8Bgmqxnvxnh0nbxeT5p/dWChA=
-modernc.org/ccgo/v3 v3.17.0/go.mod h1:Sg3fwVpmLvCUTaqEUjiBDAvshIaKDB0RXaf+zgqFu8I=
-modernc.org/ccgo/v4 v4.23.12 h1:UF08a38c4B+K3VoGipBrVWLFUCHd8+X20QZtFAIlQNk=
-modernc.org/ccgo/v4 v4.23.12/go.mod h1:vdN4h2WR5aEoNondUx26K7G8X+nuBscYnAEWSRmN2/0=
+modernc.org/cc/v4 v4.25.2 h1:T2oH7sZdGvTaie0BRNFbIYsabzCxUQg8nLqCdQ2i0ic=
+modernc.org/cc/v4 v4.25.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo=
+modernc.org/ccgo/v4 v4.23.16/go.mod h1:nNma8goMTY7aQZQNTyN9AIoJfxav4nvTnvKThAeMDdo=
+modernc.org/ccgo/v4 v4.25.1 h1:TFSzPrAGmDsdnhT9X2UrcPMI3N/mJ9/X9ykKXwLhDsU=
+modernc.org/ccgo/v4 v4.25.1/go.mod h1:njjuAYiPflywOOrm3B7kCB444ONP5pAVr8PIEoE0uDw=
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
-modernc.org/gc/v2 v2.6.1 h1:+Qf6xdG8l7B27TQ8D8lw/iFMUj1RXRBOuMUWziJOsk8=
-modernc.org/gc/v2 v2.6.1/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
-modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9 h1:ovz6yUKX71igz2yvk4NpiCL5fvdjZAI+DhuDEGx1xyU=
-modernc.org/gc/v3 v3.0.0-20241213165251-3bc300f6d0c9/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4=
-modernc.org/libc v1.61.8 h1:50KrjlFFoKq9ABh+bNVUf5SfVfQ4NY7CEyFBh65qc60=
-modernc.org/libc v1.61.8/go.mod h1:XloulGc0yIRM+91kbwrp7jNi/mfYPAvDOD2qwzWEij0=
+modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw=
+modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
+modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
+modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
+modernc.org/libc v1.62.1 h1:s0+fv5E3FymN8eJVmnk0llBe6rOxCu/DEU+XygRbS8s=
+modernc.org/libc v1.62.1/go.mod h1:iXhATfJQLjG3NWy56a6WVU73lWOcdYVxsvwCgoPljuo=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI=
modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU=
+modernc.org/memory v1.9.1 h1:V/Z1solwAVmMW1yttq3nDdZPJqV1rM05Ccq6KMSZ34g=
+modernc.org/memory v1.9.1/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
-modernc.org/sqlite v1.34.5 h1:Bb6SR13/fjp15jt70CL4f18JIN7p7dnMExd+UFnF15g=
-modernc.org/sqlite v1.34.5/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE=
modernc.org/sqlite v1.36.0 h1:EQXNRn4nIS+gfsKeUTymHIz1waxuv5BzU7558dHSfH8=
modernc.org/sqlite v1.36.0/go.mod h1:7MPwH7Z6bREicF9ZVUR78P1IKuxfZ8mRIDHD0iD+8TU=
+modernc.org/sqlite v1.37.0 h1:s1TMe7T3Q3ovQiK2Ouz4Jwh7dw4ZDqbebSDTlSJdfjI=
+modernc.org/sqlite v1.37.0/go.mod h1:5YiWv+YviqGMuGw4V+PNplcyaJ5v+vQd7TQOgkACoJM=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
diff --git a/services/ical/model/eventModel.go b/services/ical/model/eventModel.go
index 511ad22..cb5443a 100644
--- a/services/ical/model/eventModel.go
+++ b/services/ical/model/eventModel.go
@@ -17,7 +17,7 @@
package model
import (
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
"slices"
"sort"
"strings"
@@ -69,7 +69,7 @@ type Event struct {
BookedAt string `db:"BookedAt" json:"bookedAt"`
Course string `db:"course" json:"course"`
Semester string `db:"semester" json:"semester"`
- models.BaseModel
+ core.BaseModel
}
type EventType struct {
diff --git a/services/ical/model/eventModel_test.go b/services/ical/model/eventModel_test.go
index bee7eb5..1122d1a 100644
--- a/services/ical/model/eventModel_test.go
+++ b/services/ical/model/eventModel_test.go
@@ -17,7 +17,7 @@
package model
import (
- "github.com/pocketbase/pocketbase/models"
+ "github.com/pocketbase/pocketbase/core"
"reflect"
"testing"
"time"
@@ -90,7 +90,7 @@ func TestEvent_Equals(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
event Event
@@ -167,7 +167,7 @@ func TestEvent_AnonymizeEvent(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
@@ -237,7 +237,7 @@ func TestEvent_GetName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
@@ -297,7 +297,7 @@ func TestEvent_SetCourse(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
course string
@@ -357,7 +357,7 @@ func TestEvent_SetName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
type args struct {
name string
@@ -417,7 +417,7 @@ func TestEvent_TableName(t *testing.T) {
BookedAt string
Course string
Semester string
- BaseModel models.BaseModel
+ BaseModel core.BaseModel
}
tests := []struct {
name string
diff --git a/services/ical/service/ical/ical.go b/services/ical/service/ical/ical.go
index dd8b8b2..17045b2 100644
--- a/services/ical/service/ical/ical.go
+++ b/services/ical/service/ical/ical.go
@@ -28,7 +28,7 @@ import (
const expirationTime = 5 * time.Minute
-var FeedDeletedError = fmt.Errorf("feed deleted")
+var ErrFeedDeleted = fmt.Errorf("feed deleted")
func Feed(app model.AppType, token string, userAgent string) (string, string, error) {
@@ -50,7 +50,7 @@ func Feed(app model.AppType, token string, userAgent string) (string, string, er
}
if feed.Deleted {
- return "", "", FeedDeletedError
+ return "", "", ErrFeedDeleted
}
// Get all events for modules
diff --git a/services/ical/service/routes.go b/services/ical/service/routes.go
index 18c35bf..0b14b2d 100644
--- a/services/ical/service/routes.go
+++ b/services/ical/service/routes.go
@@ -41,7 +41,7 @@ func AddFeedRoutes(app model.AppType) {
results, eTag, err := ical.Feed(app, token, userAgent)
- if errors.Is(err, ical.FeedDeletedError) {
+ if errors.Is(err, ical.ErrFeedDeleted) {
return c.SendStatus(fiber.StatusGone)
}