Compare commits

...

2 Commits

29 changed files with 358 additions and 368 deletions

View File

@@ -30,7 +30,7 @@ interface BankAccount {
mandate_reference: string | ""; mandate_reference: string | "";
} }
interface DriversLicence { interface Licence {
id: number | -1; id: number | -1;
status: number | -1; status: number | -1;
licence_number: string | ""; licence_number: string | "";
@@ -63,7 +63,7 @@ interface User {
payment_status: number | -1; payment_status: number | -1;
membership: Membership; membership: Membership;
bank_account: BankAccount; bank_account: BankAccount;
drivers_licence: DriversLicence; licence: Licence;
notes: string | ""; notes: string | "";
} }
@@ -72,6 +72,7 @@ declare global {
// interface Error {} // interface Error {}
interface Locals { interface Locals {
user: User; user: User;
users: User[];
subscriptions: Subscription[]; subscriptions: Subscription[];
licence_categories: LicenceCategory[]; licence_categories: LicenceCategory[];
} }

View File

@@ -25,7 +25,6 @@ export async function handle({ event, resolve }) {
event.cookies.delete("jwt", { path: "/" }); event.cookies.delete("jwt", { path: "/" });
return await resolve(event); return await resolve(event);
} }
// find the user based on the jwt
const data = await response.json(); const data = await response.json();
@@ -62,13 +61,13 @@ export async function handle({ event, resolve }) {
event.locals.user.membership.end_date.split("T")[0]; event.locals.user.membership.end_date.split("T")[0];
} }
} }
if (event.locals.user.drivers_licence?.issued_date) { if (event.locals.user.licence?.issued_date) {
event.locals.user.drivers_licence.issued_date = event.locals.user.licence.issued_date =
event.locals.user.drivers_licence.issued_date.split("T")[0]; event.locals.user.licence.issued_date.split("T")[0];
} }
if (event.locals.user.drivers_licence?.expiration_date) { if (event.locals.user.licence?.expiration_date) {
event.locals.user.drivers_licence.expiration_date = event.locals.user.licence.expiration_date =
event.locals.user.drivers_licence.expiration_date.split("T")[0]; event.locals.user.licence.expiration_date.split("T")[0];
} }
if ( if (
event.locals.user.bank_account && event.locals.user.bank_account &&

View File

@@ -106,7 +106,7 @@
case "licence_number": case "licence_number":
return typeof value === "string" && value.length == 11 return typeof value === "string" && value.length == 11
? null ? null
: $t("validation.drivers_licence"); : $t("validation.licence");
default: default:
return typeof value === "string" && !value.trim() && required return typeof value === "string" && !value.trim() && required

View File

@@ -1,12 +1,9 @@
<script> <script>
import InputField from "$lib/components/InputField.svelte"; import InputField from "$lib/components/InputField.svelte";
import SmallLoader from "$lib/components/SmallLoader.svelte"; import SmallLoader from "$lib/components/SmallLoader.svelte";
import { onMount } from "svelte";
import { applyAction, enhance } from "$app/forms"; import { applyAction, enhance } from "$app/forms";
import { page } from "$app/stores";
import { receive, send } from "$lib/utils/helpers"; import { receive, send } from "$lib/utils/helpers";
import { t } from "svelte-i18n"; import { t } from "svelte-i18n";
import { fly } from "svelte/transition";
/** @type {import('../../routes/auth/about/[id]/$types').ActionData} */ /** @type {import('../../routes/auth/about/[id]/$types').ActionData} */
export let form; export let form;
@@ -88,10 +85,6 @@
); );
} }
onMount(() => {
console.dir(user);
});
/** /**
* Sets the active tab * Sets the active tab
* @param {string} tab - The tab to set as active * @param {string} tab - The tab to set as active
@@ -277,14 +270,14 @@
name="licence_status" name="licence_status"
type="select" type="select"
label={$t("status")} label={$t("status")}
bind:value={user.drivers_licence.status} bind:value={user.licence.status}
options={licenceStatusOptions} options={licenceStatusOptions}
/> />
<InputField <InputField
name="licence_number" name="licence_number"
type="text" type="text"
label={$t("licence_number")} label={$t("licence_number")}
bind:value={user.drivers_licence.licence_number} bind:value={user.licence.licence_number}
placeholder={$t("placeholder.licence_number")} placeholder={$t("placeholder.licence_number")}
toUpperCase={true} toUpperCase={true}
/> />
@@ -292,20 +285,20 @@
name="issued_date" name="issued_date"
type="date" type="date"
label={$t("issued_date")} label={$t("issued_date")}
bind:value={user.drivers_licence.issued_date} bind:value={user.licence.issued_date}
placeholder={$t("placeholder.issued_date")} placeholder={$t("placeholder.issued_date")}
/> />
<InputField <InputField
name="expiration_date" name="expiration_date"
type="date" type="date"
label={$t("expiration_date")} label={$t("expiration_date")}
bind:value={user.drivers_licence.expiration_date} bind:value={user.licence.expiration_date}
placeholder={$t("placeholder.expiration_date")} placeholder={$t("placeholder.expiration_date")}
/> />
<InputField <InputField
name="country" name="country"
label={$t("country")} label={$t("country")}
bind:value={user.drivers_licence.country} bind:value={user.licence.country}
placeholder={$t("placeholder.issuing_country")} placeholder={$t("placeholder.issuing_country")}
/> />
<div class="licence-categories"> <div class="licence-categories">
@@ -323,8 +316,8 @@
name="licence_categories[]" name="licence_categories[]"
value={JSON.stringify(category)} value={JSON.stringify(category)}
label={category.category} label={category.category}
checked={user.drivers_licence.licence_categories != null && checked={user.licence.licence_categories != null &&
user.drivers_licence.licence_categories.some( user.licence.licence_categories.some(
(cat) => cat.category === category.category (cat) => cat.category === category.category
)} )}
/> />

View File

@@ -44,7 +44,7 @@ export default {
iban: "Ungültige IBAN", iban: "Ungültige IBAN",
date: "Bitte geben Sie ein Datum ein", date: "Bitte geben Sie ein Datum ein",
email: "Ungültige Emailadresse", email: "Ungültige Emailadresse",
drivers_licence: "Nummer zu kurz(11 Zeichen)", licence: "Nummer zu kurz(11 Zeichen)",
}, },
server: { server: {
error: { error: {

View File

@@ -1,5 +1,5 @@
/** @type {import('./$types').LayoutLoad} */ /** @type {import('./$types').LayoutLoad} */
export async function load({ fetch, url, data }) { export async function load({ fetch, url, data }) {
const { user, subscriptions, licence_categories } = data; const { user } = data;
return { fetch, url: url.pathname, user, subscriptions, licence_categories }; return { fetch, url: url.pathname, user };
} }

View File

@@ -2,7 +2,5 @@
export async function load({ locals }) { export async function load({ locals }) {
return { return {
user: locals.user, user: locals.user,
subscriptions: locals.subscriptions,
licence_categories: locals.licence_categories,
}; };
} }

View File

@@ -0,0 +1,5 @@
/** @type {import('./$types').LayoutLoad} */
export async function load({ fetch, url, data }) {
const { user, subscriptions, licence_categories } = data;
return { fetch, url: url.pathname, user, subscriptions, licence_categories };
}

View File

@@ -0,0 +1,66 @@
import { BASE_API_URI } from "$lib/utils/constants";
/** @type {import('./$types').LayoutServerLoad} */
export async function load({ cookies, fetch, locals }) {
const jwt = cookies.get("jwt");
try {
// Fetch user data, subscriptions, and licence categories in parallel
const [subscriptionsResponse, licenceCategoriesResponse] =
await Promise.all([
fetch(`${BASE_API_URI}/backend/membership/subscriptions`, {
credentials: "include",
headers: { Cookie: `jwt=${jwt}` },
}),
fetch(`${BASE_API_URI}/backend/licence/categories`, {
credentials: "include",
headers: { Cookie: `jwt=${jwt}` },
}),
]);
// Check if any of the responses are not ok
if (!subscriptionsResponse.ok || !licenceCategoriesResponse.ok) {
cookies.delete("jwt", { path: "/" });
throw new Error("One or more API requests failed");
}
// Parse the JSON responses
const [subscriptionsData, licence_categoriesData] = await Promise.all([
subscriptionsResponse.json(),
licenceCategoriesResponse.json(),
]);
// Check if the server sent a new token
const newToken =
subscriptionsResponse.headers.get("Set-Cookie") == null
? licenceCategoriesResponse.headers.get("Set-Cookie")
: subscriptionsResponse.headers.get("Set-Cookie");
if (newToken) {
const match = newToken.match(/jwt=([^;]+)/);
if (match) {
cookies.set("jwt", match[1], {
path: "/",
httpOnly: true,
secure: process.env.NODE_ENV === "production", // Secure in production
sameSite: "lax",
maxAge: 5 * 24 * 60 * 60, // 5 days in seconds
});
}
}
console.dir(subscriptionsData);
console.dir(licence_categoriesData);
return {
user: locals.user,
subscriptions: subscriptionsData.subscriptions,
licence_categories: licence_categoriesData.licence_categories,
};
} catch (error) {
console.error("Error fetching data:", error);
// In case of any error, clear the JWT cookie
cookies.delete("jwt", { path: "/" });
return {
user: locals.user,
subscriptions: null,
licence_categories: null,
};
}
}

View File

@@ -72,7 +72,7 @@ export const actions = {
bic: String(formData.get("bic")), bic: String(formData.get("bic")),
mandate_reference: String(formData.get("mandate_reference")), mandate_reference: String(formData.get("mandate_reference")),
}, },
drivers_licence: { licence: {
id: Number(formData.get("drivers_licence_id")), id: Number(formData.get("drivers_licence_id")),
status: Number(formData.get("licence_status")), status: Number(formData.get("licence_status")),
licence_number: String(formData.get("licence_number")), licence_number: String(formData.get("licence_number")),
@@ -128,13 +128,13 @@ export const actions = {
locals.user.bank_account.mandate_date_signed = locals.user.bank_account.mandate_date_signed =
locals.user.bank_account.mandate_date_signed.split("T")[0]; locals.user.bank_account.mandate_date_signed.split("T")[0];
} }
if (locals.user.drivers_licence?.issued_date) { if (locals.user.licence?.issued_date) {
locals.user.drivers_licence.issued_date = locals.user.licence.issued_date =
locals.user.drivers_licence.issued_date.split("T")[0]; locals.user.licence.issued_date.split("T")[0];
} }
if (locals.user.drivers_licence?.expiration_date) { if (locals.user.licence?.expiration_date) {
locals.user.drivers_licence.expiration_date = locals.user.licence.expiration_date =
locals.user.drivers_licence.expiration_date.split("T")[0]; locals.user.licence.expiration_date.split("T")[0];
} }
throw redirect(303, `/auth/about/${response.id}`); throw redirect(303, `/auth/about/${response.id}`);
}, },

View File

@@ -12,14 +12,7 @@
/** @type {import('./$types').ActionData} */ /** @type {import('./$types').ActionData} */
export let form; export let form;
/** @type {App.Locals['subscriptions']}*/ $: ({ user, subscriptions, licence_categories } = $page.data);
$: subscriptions = $page.data.subscriptions;
/** @type {App.Locals['user']}*/
$: user = $page.data.user;
/** @type {App.Locals['licence_categories']} */
$: licence_categories = $page.data.licence_categories;
let showModal = false; let showModal = false;
@@ -110,89 +103,6 @@
{/if} {/if}
<style> <style>
.category-break {
grid-column: 1 / -1;
height: 1px;
background-color: #ccc;
margin-top: 10px;
margin-left: 20%;
width: 60%;
opacity: 0.4;
}
.licence-categories {
margin-bottom: 20px;
}
.checkbox-grid {
display: grid;
grid-template-columns: 1fr;
gap: 0px;
}
.checkbox-item {
display: flex;
justify-content: space-between;
align-items: center;
}
.checkbox-label-container {
flex: 0 0 auto;
width: 4em;
margin-right: 5px;
}
.checkbox-description {
flex: 1;
font-size: 15px;
color: #9b9b9b;
margin-left: 10px;
}
@media (min-width: 768px) {
.checkbox-grid {
grid-template-columns: 1fr 1fr;
gap: 0px;
}
}
@media (max-width: 480px) {
.checkbox-item {
flex-direction: column;
align-items: flex-start;
}
.checkbox-description {
margin-left: 24px;
margin-top: 5px;
text-align: left;
}
}
.subscription-info {
display: flex;
flex-wrap: wrap;
gap: 1rem;
margin-top: 1rem;
font-size: 0.9rem;
}
.subscription-column {
flex: 1;
min-width: 200px;
}
.subscription-column p {
margin: 0.5rem 0;
}
.subscription-column strong {
display: inline-block;
min-width: 100px;
}
.tab-content {
padding: 1rem;
border-radius: 0 0 3px 3px;
}
.hero-container .hero-subtitle:not(:last-of-type) { .hero-container .hero-subtitle:not(:last-of-type) {
margin: 0 0 0 0; margin: 0 0 0 0;
} }
@@ -247,25 +157,4 @@
.value { .value {
font-size: 1.1rem; font-size: 1.1rem;
} }
.button-container {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
margin-top: 1rem;
width: 100%;
}
.button-container button {
flex: 1 1 0;
min-width: 120px;
max-width: calc(50%-5px);
}
@media (max-width: 480px) {
.button-container button {
flex-basis: 100%;
max-width: none;
}
}
</style> </style>

View File

@@ -99,13 +99,13 @@ func TestSuite(t *testing.T) {
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{} var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo} membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{} var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{} var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo} userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
driversLicenceService := &services.DriversLicenceService{Repo: licenceRepo} licenceService := &services.LicenceService{Repo: licenceRepo}
Uc = &UserController{Service: userService, DriversLicenceService: driversLicenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService} Uc = &UserController{Service: userService, LicenceService: licenceService, EmailService: emailService, ConsentService: consentService, BankAccountService: bankAccountService, MembershipService: membershipService}
Mc = &MembershipController{Service: *membershipService} Mc = &MembershipController{Service: *membershipService}
Cc = &ContactController{EmailService: emailService} Cc = &ContactController{EmailService: emailService}
@@ -147,23 +147,23 @@ func TestSuite(t *testing.T) {
} }
func initLicenceCategories() error { func initLicenceCategories() error {
categories := []models.LicenceCategory{ categories := []models.Category{
{Category: "AM"}, {Name: "AM"},
{Category: "A1"}, {Name: "A1"},
{Category: "A2"}, {Name: "A2"},
{Category: "A"}, {Name: "A"},
{Category: "B"}, {Name: "B"},
{Category: "C1"}, {Name: "C1"},
{Category: "C"}, {Name: "C"},
{Category: "D1"}, {Name: "D1"},
{Category: "D"}, {Name: "D"},
{Category: "BE"}, {Name: "BE"},
{Category: "C1E"}, {Name: "C1E"},
{Category: "CE"}, {Name: "CE"},
{Category: "D1E"}, {Name: "D1E"},
{Category: "DE"}, {Name: "DE"},
{Category: "T"}, {Name: "T"},
{Category: "L"}, {Name: "L"},
} }
for _, category := range categories { for _, category := range categories {
result := database.DB.Create(&category) result := database.DB.Create(&category)
@@ -258,7 +258,7 @@ func getBaseUser() models.User {
Phone: "01738484993", Phone: "01738484993",
BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"}, BankAccount: models.BankAccount{IBAN: "DE89370400440532013000"},
Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}}, Membership: models.Membership{SubscriptionModel: models.SubscriptionModel{Name: "Basic"}},
DriversLicence: models.DriversLicence{}, Licence: models.Licence{},
ProfilePicture: "", ProfilePicture: "",
Password: "password123", Password: "password123",
Company: "", Company: "",

View File

@@ -0,0 +1,31 @@
package controllers
import (
"GoMembership/internal/services"
"GoMembership/pkg/logger"
"net/http"
"github.com/gin-gonic/gin"
)
type LicenceController struct {
Service services.LicenceService
}
func (lc *LicenceController) GetAllCategories(c *gin.Context) {
categories, err := lc.Service.GetAllCategories()
if err != nil {
logger.Error.Printf("Error retrieving licence categories: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
"field": "general",
"key": "validation.internal_server_error",
}}})
return
}
logger.Error.Printf("categories: %v", categories)
c.JSON(http.StatusOK, gin.H{
"licence_categories": categories,
})
}

View File

@@ -46,3 +46,19 @@ func (mc *MembershipController) RegisterSubscription(c *gin.Context) {
"id": id, "id": id,
}) })
} }
func (mc *MembershipController) GetSubscriptions(c *gin.Context) {
subscriptions, err := mc.Service.GetSubscriptions(nil)
if err != nil {
logger.Error.Printf("Error retrieving subscriptions: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
"field": "general",
"key": "validation.internal_server_error",
}}})
return
}
c.JSON(http.StatusOK, gin.H{
"subscriptions": subscriptions,
})
}

View File

@@ -24,7 +24,7 @@ type UserController struct {
ConsentService services.ConsentServiceInterface ConsentService services.ConsentServiceInterface
BankAccountService services.BankAccountServiceInterface BankAccountService services.BankAccountServiceInterface
MembershipService services.MembershipServiceInterface MembershipService services.MembershipServiceInterface
DriversLicenceService services.DriversLicenceInterface LicenceService services.LicenceInterface
} }
type RegistrationData struct { type RegistrationData struct {
@@ -172,28 +172,8 @@ func (uc *UserController) CurrentUserHandler(c *gin.Context) {
return return
} }
subscriptions, err := uc.MembershipService.GetSubscriptions(nil)
if err != nil {
logger.Error.Printf("Error retrieving subscriptions: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
"field": "general",
"key": "validation.internal_server_error",
}}})
return
}
licenceCategories, err := uc.DriversLicenceService.GetAllCategories()
if err != nil {
logger.Error.Printf("Error retrieving licence categories: %v", err)
c.JSON(http.StatusInternalServerError, gin.H{"errors": []gin.H{{
"field": "general",
"key": "validation.internal_server_error",
}}})
return
}
c.JSON(http.StatusOK, gin.H{ c.JSON(http.StatusOK, gin.H{
"user": user.Safe(), "user": user.Safe(),
"subscriptions": subscriptions,
"licence_categories": licenceCategories,
}) })
} }

View File

@@ -75,7 +75,7 @@ func testUserController(t *testing.T) {
loginEmail, loginCookie := testLoginHandler(t) loginEmail, loginCookie := testLoginHandler(t)
logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie) logoutCookie := testCurrentUserHandler(t, loginEmail, loginCookie)
testUpdateUser(t, loginEmail, loginCookie) testUpdateUser(t, loginCookie)
testLogoutHandler(t, logoutCookie) testLogoutHandler(t, logoutCookie)
} }
@@ -413,7 +413,7 @@ func validateUser(assert bool, wantDBData map[string]interface{}) error {
return nil return nil
} }
func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) { func testUpdateUser(t *testing.T, loginCookie http.Cookie) {
invalidCookie := http.Cookie{ invalidCookie := http.Cookie{
Name: "jwt", Name: "jwt",
@@ -480,7 +480,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
}, },
}, },
{ {
name: "Change LicenceNumber", name: "Change Number",
setupCookie: func(req *http.Request) { setupCookie: func(req *http.Request) {
req.AddCookie(&loginCookie) req.AddCookie(&loginCookie)
}, },
@@ -489,7 +489,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.FirstName = "John Updated" u.FirstName = "John Updated"
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
}, },
@@ -503,11 +503,11 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.FirstName = "John Updated" u.FirstName = "John Updated"
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{} var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
category, err := licenceRepo.FindCategoryByName("B") category, err := licenceRepo.FindCategoryByName("B")
assert.NoError(t, err) assert.NoError(t, err)
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category} u.Licence.Categories = []models.Category{category}
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
}, },
@@ -521,12 +521,12 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.FirstName = "John Updated" u.FirstName = "John Updated"
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{} var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
category, err := licenceRepo.FindCategoryByName("A") category, err := licenceRepo.FindCategoryByName("A")
category2, err := licenceRepo.FindCategoryByName("BE") category2, err := licenceRepo.FindCategoryByName("BE")
assert.NoError(t, err) assert.NoError(t, err)
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category, category2} u.Licence.Categories = []models.Category{category, category2}
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
}, },
@@ -540,11 +540,11 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.FirstName = "John Updated" u.FirstName = "John Updated"
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{} var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
category, err := licenceRepo.FindCategoryByName("A") category, err := licenceRepo.FindCategoryByName("A")
assert.NoError(t, err) assert.NoError(t, err)
u.DriversLicence.LicenceCategories = []models.LicenceCategory{category} u.Licence.Categories = []models.Category{category}
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
}, },
@@ -558,8 +558,8 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.FirstName = "John Updated" u.FirstName = "John Updated"
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
u.DriversLicence.LicenceCategories = []models.LicenceCategory{} u.Licence.Categories = []models.Category{}
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
}, },
@@ -573,7 +573,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.ID = 1 u.ID = 1
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
u.FirstName = "John Missing ID" u.FirstName = "John Missing ID"
}, },
expectedStatus: http.StatusForbidden, expectedStatus: http.StatusForbidden,
@@ -590,7 +590,7 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
u.Password = "" u.Password = ""
u.LastName = "Doe Updated" u.LastName = "Doe Updated"
u.Phone = "01738484994" u.Phone = "01738484994"
u.DriversLicence.LicenceNumber = "B072RRE2I50" u.Licence.Number = "B072RRE2I50"
u.Password = "NewPassword" u.Password = "NewPassword"
}, },
expectedStatus: http.StatusAccepted, expectedStatus: http.StatusAccepted,
@@ -713,23 +713,23 @@ func testUpdateUser(t *testing.T, loginEmail string, loginCookie http.Cookie) {
assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch") assert.Equal(t, updatedUser.Membership.SubscriptionModelID, updatedUserFromDB.Membership.SubscriptionModelID, "Membership.SubscriptionModelID mismatch")
assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch") assert.Equal(t, updatedUser.Membership.ParentMembershipID, updatedUserFromDB.Membership.ParentMembershipID, "Membership.ParentMembershipID mismatch")
if updatedUser.DriversLicence.Status == 0 { if updatedUser.Licence.Status == 0 {
updatedUser.DriversLicence.Status = constants.UnverifiedStatus updatedUser.Licence.Status = constants.UnverifiedStatus
} }
assert.Equal(t, updatedUser.DriversLicence.Status, updatedUserFromDB.DriversLicence.Status, "DriversLicence.Status mismatch") assert.Equal(t, updatedUser.Licence.Status, updatedUserFromDB.Licence.Status, "Licence.Status mismatch")
assert.Equal(t, updatedUser.DriversLicence.LicenceNumber, updatedUserFromDB.DriversLicence.LicenceNumber, "DriversLicence.LicenceNumber mismatch") assert.Equal(t, updatedUser.Licence.Number, updatedUserFromDB.Licence.Number, "Licence.Number mismatch")
assert.Equal(t, updatedUser.DriversLicence.IssuedDate, updatedUserFromDB.DriversLicence.IssuedDate, "DriversLicence.IssuedDate mismatch") assert.Equal(t, updatedUser.Licence.IssuedDate, updatedUserFromDB.Licence.IssuedDate, "Licence.IssuedDate mismatch")
assert.Equal(t, updatedUser.DriversLicence.ExpirationDate, updatedUserFromDB.DriversLicence.ExpirationDate, "DriversLicence.ExpirationDate mismatch") assert.Equal(t, updatedUser.Licence.ExpirationDate, updatedUserFromDB.Licence.ExpirationDate, "Licence.ExpirationDate mismatch")
assert.Equal(t, updatedUser.DriversLicence.IssuingCountry, updatedUserFromDB.DriversLicence.IssuingCountry, "DriversLicence.IssuingCountry mismatch") assert.Equal(t, updatedUser.Licence.IssuingCountry, updatedUserFromDB.Licence.IssuingCountry, "Licence.IssuingCountry mismatch")
// For slices or more complex nested structures, you might want to use deep equality checks // For slices or more complex nested structures, you might want to use deep equality checks
assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch") assert.ElementsMatch(t, updatedUser.Consents, updatedUserFromDB.Consents, "Consents mismatch")
if len(updatedUser.DriversLicence.LicenceCategories) > 0 { if len(updatedUser.Licence.Categories) > 0 {
for i := range updatedUser.DriversLicence.LicenceCategories { for i := range updatedUser.Licence.Categories {
assert.Equal(t, updatedUser.DriversLicence.LicenceCategories[i].Category, updatedUserFromDB.DriversLicence.LicenceCategories[i].Category, "LicenceCategory Category mismatch at index %d", i) assert.Equal(t, updatedUser.Licence.Categories[i].Name, updatedUserFromDB.Licence.Categories[i].Name, "Category Category mismatch at index %d", i)
} }
} else { } else {
assert.Emptyf(t, updatedUserFromDB.DriversLicence.LicenceCategories, "Categories aren't empty when they should") assert.Emptyf(t, updatedUserFromDB.Licence.Categories, "Categories aren't empty when they should")
} }
} }
}) })
@@ -1094,18 +1094,18 @@ func getTestUsers() []RegisterUserTest {
Assert: false, Assert: false,
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User { Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
user.Email = "john.wronglicence.doe@example.com" user.Email = "john.wronglicence.doe@example.com"
user.DriversLicence.LicenceNumber = "AAAA12345AA" user.Licence.Number = "AAAA12345AA"
return user return user
})), })),
}, },
{ {
Name: "Correct DriversLicence number, should pass", Name: "Correct Licence number, should pass",
WantResponse: http.StatusCreated, WantResponse: http.StatusCreated,
WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"}, WantDBData: map[string]interface{}{"email": "john.correctLicenceNumber@example.com"},
Assert: true, Assert: true,
Input: GenerateInputJSON(customizeInput(func(user models.User) models.User { Input: GenerateInputJSON(customizeInput(func(user models.User) models.User {
user.Email = "john.correctLicenceNumber@example.com" user.Email = "john.correctLicenceNumber@example.com"
user.DriversLicence.LicenceNumber = "B072RRE2I55" user.Licence.Number = "B072RRE2I55"
return user return user
})), })),
}, },

View File

@@ -27,8 +27,8 @@ func Open(dbPath string, adminMail string) error {
&models.Membership{}, &models.Membership{},
&models.Consent{}, &models.Consent{},
&models.Verification{}, &models.Verification{},
&models.DriversLicence{}, &models.Licence{},
&models.LicenceCategory{}, &models.Category{},
&models.BankAccount{}); err != nil { &models.BankAccount{}); err != nil {
logger.Error.Fatalf("Couldn't create database: %v", err) logger.Error.Fatalf("Couldn't create database: %v", err)
return err return err
@@ -82,24 +82,24 @@ func createSubscriptionModels() []models.SubscriptionModel {
} }
} }
func createLicenceCategories() []models.LicenceCategory { func createLicenceCategories() []models.Category {
return []models.LicenceCategory{ return []models.Category{
{Category: "AM"}, {Name: "AM"},
{Category: "A1"}, {Name: "A1"},
{Category: "A2"}, {Name: "A2"},
{Category: "A"}, {Name: "A"},
{Category: "B"}, {Name: "B"},
{Category: "C1"}, {Name: "C1"},
{Category: "C"}, {Name: "C"},
{Category: "D1"}, {Name: "D1"},
{Category: "D"}, {Name: "D"},
{Category: "BE"}, {Name: "BE"},
{Category: "C1E"}, {Name: "C1E"},
{Category: "CE"}, {Name: "CE"},
{Category: "D1E"}, {Name: "D1E"},
{Category: "DE"}, {Name: "DE"},
{Category: "T"}, {Name: "T"},
{Category: "L"}, {Name: "L"},
} }
} }
@@ -143,7 +143,7 @@ func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error
SubscriptionModelID: subscriptionModelID, SubscriptionModelID: subscriptionModelID,
}, },
BankAccount: models.BankAccount{}, BankAccount: models.BankAccount{},
DriversLicence: models.DriversLicence{ Licence: models.Licence{
Status: constants.UnverifiedStatus, Status: constants.UnverifiedStatus,
}, },
}, nil }, nil

View File

@@ -4,17 +4,17 @@ import (
"time" "time"
) )
type DriversLicence struct { type Licence struct {
ID uint `json:"id" gorm:"primaryKey"` ID uint `json:"id" gorm:"primaryKey"`
Status int8 `json:"status" binding:"omitempty,number"` Status int8 `json:"status" binding:"omitempty,number"`
LicenceNumber string `json:"number" binding:"omitempty,euDriversLicence,safe_content"` Number string `json:"number" binding:"omitempty,euDriversLicence,safe_content"`
IssuedDate time.Time `json:"issued_date" binding:"omitempty,lte"` IssuedDate time.Time `json:"issued_date" binding:"omitempty,lte"`
ExpirationDate time.Time `json:"expiration_date" binding:"omitempty,gt"` ExpirationDate time.Time `json:"expiration_date" binding:"omitempty,gt"`
IssuingCountry string `json:"country" binding:"safe_content"` IssuingCountry string `json:"country" binding:"safe_content"`
LicenceCategories []LicenceCategory `json:"licence_categories" gorm:"many2many:licence_2_categories"` Categories []Category `json:"licence_categories" gorm:"many2many:licence_2_categories"`
} }
type LicenceCategory struct { type Category struct {
ID uint `json:"id" gorm:"primaryKey"` ID uint `json:"id" gorm:"primaryKey"`
Category string `json:"category" binding:"safe_content"` Name string `json:"category" binding:"safe_content"`
} }

View File

@@ -29,8 +29,8 @@ type User struct {
VerificationID uint VerificationID uint
Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"` Membership Membership `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"membership"`
MembershipID uint MembershipID uint
DriversLicence DriversLicence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"drivers_licence"` Licence Licence `gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" json:"licence"`
DriversLicenceID uint LicenceID uint
ID uint `json:"id"` ID uint `json:"id"`
PaymentStatus int8 `json:"payment_status"` PaymentStatus int8 `json:"payment_status"`
Status int8 `json:"status"` Status int8 `json:"status"`
@@ -99,14 +99,14 @@ func (u *User) Safe() map[string]interface{} {
"bic": u.BankAccount.BIC, "bic": u.BankAccount.BIC,
"mandate_reference": u.BankAccount.MandateReference, "mandate_reference": u.BankAccount.MandateReference,
}, },
"drivers_licence": map[string]interface{}{ "licence": map[string]interface{}{
"id": u.DriversLicence.ID, "id": u.Licence.ID,
"licence_number": u.DriversLicence.LicenceNumber, "number": u.Licence.Number,
"status": u.DriversLicence.Status, "status": u.Licence.Status,
"issued_date": u.DriversLicence.IssuedDate, "issued_date": u.Licence.IssuedDate,
"expiration_date": u.DriversLicence.ExpirationDate, "expiration_date": u.Licence.ExpirationDate,
"country": u.DriversLicence.IssuingCountry, "country": u.Licence.IssuingCountry,
"licence_categories": u.DriversLicence.LicenceCategories, "licence_categories": u.Licence.Categories,
}, },
} }
} }

View File

@@ -1,31 +0,0 @@
package repositories
import (
"GoMembership/internal/database"
"GoMembership/internal/models"
)
type DriversLicenceInterface interface {
FindCategoryByName(categoryName string) (models.LicenceCategory, error)
FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error)
GetAllCategories() ([]models.LicenceCategory, error)
}
type DriversLicenceRepository struct{}
func (r *DriversLicenceRepository) GetAllCategories() ([]models.LicenceCategory, error) {
var categories []models.LicenceCategory
err := database.DB.Find(&categories).Error
return categories, err
}
func (r *DriversLicenceRepository) FindCategoriesByIDs(ids []uint) ([]models.LicenceCategory, error) {
var categories []models.LicenceCategory
err := database.DB.Where("id IN ?", ids).Find(&categories).Error
return categories, err
}
func (r *DriversLicenceRepository) FindCategoryByName(categoryName string) (models.LicenceCategory, error) {
var category models.LicenceCategory
err := database.DB.Where("category = ?", categoryName).First(&category).Error
return category, err
}

View File

@@ -0,0 +1,31 @@
package repositories
import (
"GoMembership/internal/database"
"GoMembership/internal/models"
)
type LicenceInterface interface {
FindCategoryByName(categoryName string) (models.Category, error)
FindCategoriesByIDs(ids []uint) ([]models.Category, error)
GetAllCategories() ([]models.Category, error)
}
type LicenceRepository struct{}
func (r *LicenceRepository) GetAllCategories() ([]models.Category, error) {
var categories []models.Category
err := database.DB.Find(&categories).Error
return categories, err
}
func (r *LicenceRepository) FindCategoriesByIDs(ids []uint) ([]models.Category, error) {
var categories []models.Category
err := database.DB.Where("id IN ?", ids).Find(&categories).Error
return categories, err
}
func (r *LicenceRepository) FindCategoryByName(categoryName string) (models.Category, error) {
var category models.Category
err := database.DB.Where("category = ?", categoryName).First(&category).Error
return category, err
}

View File

@@ -42,7 +42,7 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
err := database.DB.Transaction(func(tx *gorm.DB) error { err := database.DB.Transaction(func(tx *gorm.DB) error {
// Check if the user exists in the database // Check if the user exists in the database
var existingUser models.User var existingUser models.User
if err := tx.Preload("DriversLicence.LicenceCategories"). if err := tx.Preload("Licence.Categories").
Preload("Membership"). Preload("Membership").
First(&existingUser, user.ID).Error; err != nil { First(&existingUser, user.ID).Error; err != nil {
return err return err
@@ -57,9 +57,9 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
} }
// Handle the update of the LicenceCategories explicitly // Handle the update of the LicenceCategories explicitly
if user.DriversLicence.ID != 0 { if user.Licence.ID != 0 {
// Replace the LicenceCategories with the new list // Replace the Categories with the new list
if err := tx.Model(&existingUser.DriversLicence).Association("LicenceCategories").Replace(user.DriversLicence.LicenceCategories); err != nil { if err := tx.Model(&existingUser.Licence).Association("Categories").Replace(user.Licence.Categories); err != nil {
return err return err
} }
} }
@@ -71,9 +71,9 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
} }
} }
// Update the DriversLicence fields if provided // Update the Licence fields if provided
if user.DriversLicence.ID != 0 { if user.Licence.ID != 0 {
if err := tx.Model(&existingUser.DriversLicence).Updates(user.DriversLicence).Error; err != nil { if err := tx.Model(&existingUser.Licence).Updates(user.Licence).Error; err != nil {
return err return err
} }
} }
@@ -86,7 +86,7 @@ func (ur *UserRepository) UpdateUser(user *models.User) (*models.User, error) {
} }
var updatedUser models.User var updatedUser models.User
if err := database.DB.Preload("DriversLicence.LicenceCategories"). if err := database.DB.Preload("Licence.Categories").
Preload("Membership"). Preload("Membership").
First(&updatedUser, user.ID).Error; err != nil { First(&updatedUser, user.ID).Error; err != nil {
return nil, err return nil, err
@@ -99,7 +99,7 @@ func (ur *UserRepository) GetUsers(where map[string]interface{}) (*[]models.User
result := database.DB. result := database.DB.
Preload(clause.Associations). Preload(clause.Associations).
Preload("Membership.SubscriptionModel"). Preload("Membership.SubscriptionModel").
Preload("DriversLicence.LicenceCategories"). Preload("Licence.Categories").
Where(where).Find(&users) Where(where).Find(&users)
if result.Error != nil { if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound { if result.Error == gorm.ErrRecordNotFound {
@@ -115,7 +115,7 @@ func GetUserByID(userID *uint) (*models.User, error) {
result := database.DB. result := database.DB.
Preload(clause.Associations). Preload(clause.Associations).
Preload("Membership.SubscriptionModel"). Preload("Membership.SubscriptionModel").
Preload("DriversLicence.LicenceCategories"). Preload("Licence.Categories").
First(&user, userID) First(&user, userID)
if result.Error != nil { if result.Error != nil {
if result.Error == gorm.ErrRecordNotFound { if result.Error == gorm.ErrRecordNotFound {

View File

@@ -7,7 +7,7 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
func RegisterRoutes(router *gin.Engine, userController *controllers.UserController, membershipcontroller *controllers.MembershipController, contactController *controllers.ContactController) { func RegisterRoutes(router *gin.Engine, userController *controllers.UserController, membershipcontroller *controllers.MembershipController, contactController *controllers.ContactController, licenceController *controllers.LicenceController) {
router.GET("/users/verify", userController.VerifyMailHandler) router.GET("/users/verify", userController.VerifyMailHandler)
router.POST("/users/register", userController.RegisterUser) router.POST("/users/register", userController.RegisterUser)
router.POST("/users/contact", contactController.RelayContactRequest) router.POST("/users/contact", contactController.RelayContactRequest)
@@ -21,12 +21,23 @@ func RegisterRoutes(router *gin.Engine, userController *controllers.UserControll
router.POST("/v1/subscription", membershipcontroller.RegisterSubscription) router.POST("/v1/subscription", membershipcontroller.RegisterSubscription)
} }
authRouter := router.Group("/backend/users") userRouter := router.Group("/backend/users")
authRouter.Use(middlewares.AuthMiddleware()) userRouter.Use(middlewares.AuthMiddleware())
{ {
authRouter.GET("/current", userController.CurrentUserHandler) userRouter.GET("/current", userController.CurrentUserHandler)
authRouter.POST("/logout", userController.LogoutHandler) userRouter.POST("/logout", userController.LogoutHandler)
authRouter.PATCH("/update", userController.UpdateHandler) userRouter.PATCH("/update", userController.UpdateHandler)
}
membershipRouter := router.Group("/backend/membership")
membershipRouter.Use(middlewares.AuthMiddleware())
{
membershipRouter.GET("/subscriptions", membershipcontroller.GetSubscriptions)
}
licenceRouter := router.Group("/backend/licence")
licenceRouter.Use(middlewares.AuthMiddleware())
{
licenceRouter.GET("/categories", licenceController.GetAllCategories)
} }
} }

View File

@@ -39,14 +39,15 @@ func Run() {
var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{} var subscriptionRepo repositories.SubscriptionModelsRepositoryInterface = &repositories.SubscriptionModelsRepository{}
membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo} membershipService := &services.MembershipService{Repo: membershipRepo, SubscriptionRepo: subscriptionRepo}
var licenceRepo repositories.LicenceInterface = &repositories.LicenceRepository{}
licenceService := &services.LicenceService{Repo: licenceRepo}
var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{} var userRepo repositories.UserRepositoryInterface = &repositories.UserRepository{}
var licenceRepo repositories.DriversLicenceInterface = &repositories.DriversLicenceRepository{}
driversLicenceService := &services.DriversLicenceService{Repo: licenceRepo}
userService := &services.UserService{Repo: userRepo, Licences: licenceRepo} userService := &services.UserService{Repo: userRepo, Licences: licenceRepo}
userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, DriversLicenceService: driversLicenceService, BankAccountService: bankAccountService, MembershipService: membershipService} userController := &controllers.UserController{Service: userService, EmailService: emailService, ConsentService: consentService, LicenceService: licenceService, BankAccountService: bankAccountService, MembershipService: membershipService}
membershipController := &controllers.MembershipController{Service: *membershipService} membershipController := &controllers.MembershipController{Service: *membershipService}
licenceController := &controllers.LicenceController{Service: *licenceService}
contactController := &controllers.ContactController{EmailService: emailService} contactController := &controllers.ContactController{EmailService: emailService}
router := gin.Default() router := gin.Default()
@@ -63,7 +64,7 @@ func Run() {
limiter := middlewares.NewIPRateLimiter(config.Security.Ratelimits.Limit, config.Security.Ratelimits.Burst) limiter := middlewares.NewIPRateLimiter(config.Security.Ratelimits.Limit, config.Security.Ratelimits.Burst)
router.Use(middlewares.RateLimitMiddleware(limiter)) router.Use(middlewares.RateLimitMiddleware(limiter))
routes.RegisterRoutes(router, userController, membershipController, contactController) routes.RegisterRoutes(router, userController, membershipController, contactController, licenceController)
validation.SetupValidators() validation.SetupValidators()
logger.Info.Println("Starting server on :8080") logger.Info.Println("Starting server on :8080")

View File

@@ -1,18 +0,0 @@
package services
import (
"GoMembership/internal/models"
"GoMembership/internal/repositories"
)
type DriversLicenceInterface interface {
GetAllCategories() ([]models.LicenceCategory, error)
}
type DriversLicenceService struct {
Repo repositories.DriversLicenceInterface
}
func (s *DriversLicenceService) GetAllCategories() ([]models.LicenceCategory, error) {
return s.Repo.GetAllCategories()
}

View File

@@ -0,0 +1,18 @@
package services
import (
"GoMembership/internal/models"
"GoMembership/internal/repositories"
)
type LicenceInterface interface {
GetAllCategories() ([]models.Category, error)
}
type LicenceService struct {
Repo repositories.LicenceInterface
}
func (s *LicenceService) GetAllCategories() ([]models.Category, error) {
return s.Repo.GetAllCategories()
}

View File

@@ -28,7 +28,7 @@ type UserServiceInterface interface {
type UserService struct { type UserService struct {
Repo repositories.UserRepositoryInterface Repo repositories.UserRepositoryInterface
Licences repositories.DriversLicenceInterface Licences repositories.LicenceInterface
} }
func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) { func (service *UserService) UpdateUser(user *models.User, userRole int8) (*models.User, error) {
@@ -38,9 +38,9 @@ func (service *UserService) UpdateUser(user *models.User, userRole int8) (*model
} }
user.UpdatedAt = time.Now() user.UpdatedAt = time.Now()
if user.DriversLicence.Status == 0 { if user.Licence.Status == 0 {
// This is a new drivers licence // This is a new drivers licence
user.DriversLicence.Status = constants.UnverifiedStatus user.Licence.Status = constants.UnverifiedStatus
} }
updatedUser, err := service.Repo.UpdateUser(user) updatedUser, err := service.Repo.UpdateUser(user)
@@ -66,7 +66,7 @@ func (service *UserService) RegisterUser(user *models.User) (uint, string, error
user.CreatedAt = time.Now() user.CreatedAt = time.Now()
user.UpdatedAt = time.Now() user.UpdatedAt = time.Now()
user.PaymentStatus = constants.AwaitingPaymentStatus user.PaymentStatus = constants.AwaitingPaymentStatus
user.DriversLicence.Status = constants.UnverifiedStatus user.Licence.Status = constants.UnverifiedStatus
user.BankAccount.MandateDateSigned = time.Now() user.BankAccount.MandateDateSigned = time.Now()
id, err := service.Repo.CreateUser(user) id, err := service.Repo.CreateUser(user)

View File

@@ -6,7 +6,7 @@ import (
"github.com/go-playground/validator/v10" "github.com/go-playground/validator/v10"
) )
func ValidateDriversLicence(fl validator.FieldLevel) bool { func ValidateLicence(fl validator.FieldLevel) bool {
fieldValue := fl.Field().String() fieldValue := fl.Field().String()
if len(fieldValue) != 11 { if len(fieldValue) != 11 {
return false return false

View File

@@ -14,7 +14,7 @@ func SetupValidators() {
v.RegisterValidation("safe_content", ValidateSafeContent) v.RegisterValidation("safe_content", ValidateSafeContent)
v.RegisterValidation("iban", IBANValidator) v.RegisterValidation("iban", IBANValidator)
v.RegisterValidation("bic", BICValidator) v.RegisterValidation("bic", BICValidator)
v.RegisterValidation("euDriversLicence", ValidateDriversLicence) v.RegisterValidation("euDriversLicence", ValidateLicence)
// Register struct-level validations // Register struct-level validations
v.RegisterStructValidation(validateUser, models.User{}) v.RegisterStructValidation(validateUser, models.User{})