Services OVERHAUL =>> using json with schemas and validators as database

This commit is contained in:
matthieu42morin 2024-03-20 16:11:46 +01:00
parent 15e7a32263
commit 449f67c2a0
8 changed files with 386 additions and 8 deletions

View File

@ -1,13 +1,15 @@
{ {
"name": "cosmeticstudio", "name": "kkosmetickysalon",
"version": "0.0.1", "version": "0.0.1",
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"dev": "vite dev --mode development", "validate": "node ./tests/ValidateServices.js",
"build": "vite build", "dev": "pnpm run validate && vite dev --mode development",
"build-dev": "vite build --mode development", "build": "pnpm run validate && vite build",
"build-dev": "pnpm run validate && vite build --mode development",
"preview": "vite preview", "preview": "vite preview",
"test": "npm run test:integration && npm run test:unit", "test": "pnpm run test:integration && npm run test:unit",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .", "lint": "prettier --plugin-search-dir . --check . && eslint .",
@ -23,7 +25,8 @@
"@fortawesome/fontawesome-free": "^6.5.1", "@fortawesome/fontawesome-free": "^6.5.1",
"@sentry/sveltekit": "^7.107.0", "@sentry/sveltekit": "^7.107.0",
"@sveltejs/adapter-node": "^5.0.1", "@sveltejs/adapter-node": "^5.0.1",
"@sveltejs/vite-plugin-svelte": "^3.0.2" "@sveltejs/vite-plugin-svelte": "^3.0.2",
"ajv": "^8.12.0"
}, },
"devDependencies": { "devDependencies": {
"@floating-ui/dom": "1.5.3", "@floating-ui/dom": "1.5.3",
@ -53,6 +56,5 @@
"vite": "^5.1.6", "vite": "^5.1.6",
"vite-plugin-tailwind-purgecss": "^0.2.0", "vite-plugin-tailwind-purgecss": "^0.2.0",
"vitest": "^0.32.4" "vitest": "^0.32.4"
}, }
"type": "module"
} }

View File

@ -0,0 +1,34 @@
{
"$schema": "/src/routes/sluzby/schema.json",
"category": "DALŠÍ VELMI OBLÍBENÉ SLUŽBY",
"items": [
{
"name": "Lifting řas booster (botox)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "lifting-ras-booster",
"price": 500,
"duration": 1
},
{
"name": "Laminace obočí + výživa",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "laminace-oboci-vyziva",
"price": 500,
"duration": 1
},
{
"name": "Úprava obočí (tvar + barva)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "uprava-oboci-tvar-barva",
"price": 250,
"duration": 1
},
{
"name": "Úprava obočí + řasy (tvar + barvení)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "uprava-oboci-rasy-tvar-barveni",
"price": 300,
"duration": 1
}
]
}

View File

@ -0,0 +1,69 @@
{
"$schema": "/src/routes/sluzby/schema.json",
"category": "Depilace",
"items": [
{
"name": "Depilace Horní ret",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-horni-ret",
"price": 80,
"duration": 0.5
},
{
"name": "Depilace Brada",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-brada",
"price": 80,
"duration": 0.5
},
{
"name": "Depilace Obočí",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-oboci",
"price": 150,
"duration": 0.5
},
{
"name": "Depilace Tváře",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-tvare",
"price": 150,
"duration": 0.5
},
{
"name": "Depilace Podpaží",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-podpazi",
"price": 150,
"duration": 0.5
},
{
"name": "Depilace Předloktí",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-predlokti",
"price": 200,
"duration": 0.5
},
{
"name": "Depilace Celé ruce",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-cele-ruce",
"price": 350,
"duration": 1
},
{
"name": "Depilace Lýtka",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-lytka",
"price": 350,
"duration": 1
},
{
"name": "Depilace Celé nohy",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "depilace-cele-nohy",
"price": 500,
"duration": 1
}
]
}

View File

@ -0,0 +1,48 @@
{
"$schema": "/src/routes/sluzby/schema.json",
"category": "Kosmetické ošetření",
"items": [
{
"name": "ZÁKLADNÍ CALM",
"description": "Diagnostika pleti, odlíčení tonizace, enzymatický peeling, kavitační peeling -ultarzvuková špachtle, séra dle typu pleti, masky (tvář,krk,dekolt), závěrečná péče (oční a denní krém)",
"id": "zakladni-calm",
"price": 500,
"duration": 1
},
{
"name": "ZÁKLADNÍ + CALM PLUS",
"description": "Diagnostika pleti, odlíčení tonizace, úprava obočí (vosk+pinzeta), barvení řas a obočí, depilace horní ret/brada, enzymatický peeling, kavitační peeling -ultarzvuková špachtle, séra dle typu pleti, masky (tvář,krk,dekolt), závěrečná péče (oční a denní krém)",
"id": "zakladni-calm-plus",
"price": 600,
"duration": 1
},
{
"name": "RELAXAČNÍ",
"description": "Diagnostika pleti, odlíčení tonizace, úprava obočí (vosk+pinzeta), barvení řas a obočí, depilace horní ret/brada, enzymatický peeling, kavitační peeling -ultarzvuková špachtle, séra, masáž relaxační (tvář,krk dekolt), masky (tvář,krk,dekolt), závěrečná péče (oční a denní krém)",
"id": "relaxacni",
"price": 690,
"duration": 1.5
},
{
"name": "LIFTINGOVÉ - ANTI AGE",
"description": "Diagnostika pleti, odlíčení tonizace, úprava obočí (vosk+pinzeta), barvení řas a obočí, depilace horní ret/brada, enzymatický peeling, kavitační peeling -ultarzvuková špachtle, vacupres ošetření lifting obličeje krku a dekoltu, séra, masky (tvář,krk,dekolt), alginátová maska, závěrečná péče (oční a denní krém)",
"id": "liftingove-anti-age",
"price": 690,
"duration": 1.5
},
{
"name": "CLEAR + ANTI AKNÉ",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "clear-anti-akne",
"price": 690,
"duration": 1.5
},
{
"name": "Odlíčení + sérum + alginátová maska (PROJASNĚNÍ)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "odliceni-serum-alginatova-maska",
"price": 300,
"duration": 1
}
]
}

View File

@ -0,0 +1,69 @@
{
"$schema": "$routes/sluzby/schema.json",
"category": "Permanentní make-up",
"items": [
{
"name": "Obočí Pudrové, Ombré",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "oboci",
"price": 3000,
"duration": 2.5
},
{
"name": "Horní linky - meziřasové přirozené",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "linky",
"price": 2000,
"duration": 2
},
{
"name": "Klasické linky - s ocáskem",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "classic-linky",
"price": 3000,
"duration": 2.5
},
{
"name": "Klasické linky - s ocáskem + spodní linky",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "classic-linky+spodni",
"price": 3500,
"duration": 2.5
},
{
"name": "Rty - kontura",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "rty",
"price": 2500,
"duration": 2
},
{
"name": "3D Rty (kontura a stínování), Full Lips (plné rty)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "3d-rty",
"price": 3500,
"duration": 2.5
},
{
"name": "Aquarelle Lips (přirodní stínování, bez kontury)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "aquarelle",
"price": 3000,
"duration": 2
},
{
"name": "První korekce po aplikaci pmu max. do 3 měsíců",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "korekce",
"price": 1000,
"duration": 1.5
},
{
"name": "Oprava práce obočí jiného salonu",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "oprava-oboci",
"price": "na domluvě",
"duration": "na domluvě"
}
]
}

View File

@ -0,0 +1,41 @@
{
"$schema": "/src/routes/sluzby/schema.json",
"category": "Vakuslim 48 - zeštíhlující procedura",
"items": [
{
"name": "Ošetření horních končetin",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "vakuslim-48-zestihlujici-procedura-horni-koncetiny",
"price": 600,
"duration": 2
},
{
"name": "1 ošetření spodní části těla (břicho, boky, dolní končetiny)",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "vakuslim-48-zestihlujici-procedura-spodni-cast-tela",
"price": 800,
"duration": 2
},
{
"name": "1 ošetření komplet horní-dolní části",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "vakuslim-48-zestihlujici-procedura-komplet-horni-dolni-cast",
"price": 1200,
"duration": 2
},
{
"name": "6 ošetření předplatné kompet",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "vakuslim-48-zestihlujici-procedura-6-o-setreni-predplatne-kompet",
"price": 6600,
"duration": 2
},
{
"name": "12 ošetření předplatné komplet",
"description": "Diagnostika pleti, odlíčení tonizace",
"id": "vakuslim-48-zestihlujici-procedura-12-o-setreni-predplatne-komplet",
"price": 11000,
"duration": 2
}
]
}

View File

@ -0,0 +1,74 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Service",
"type": "object",
"required": [
"category",
"items"
],
"properties": {
"category": {
"type": "string",
"description": "Name of the category of services",
"minLength": 4,
"default": "Permanentní makeup"
},
"items": {
"title": "Items under the category",
"type": "array",
"items": {
"type": "object",
"title": "Items",
"properties": {
"name": {
"type": "string",
"description": "Name of the service"
},
"description": {
"title": "Description",
"type": "string",
"description": "description :D",
"default": "A description of a description"
},
"id": {
"type": "string",
"description": "a short handle used in urls and on cal.com",
"default": "pmu",
"minLength": 3
},
"price": {
"title": "Price",
"description": "Price of the product",
"oneOf": [
{
"type": "number",
"description": "Price of the service as a number",
"default": 300
},
{
"type": "string",
"description": "Price of the service as a text description (e.g., 'Free')",
"default": "na dohode"
}
]
},
"duration": {
"title": "Duration",
"description": "How long will the procedure take? (can be on demand or specific amount)",
"oneOf": [
{
"type": "number",
"description": "Duration of the service in minutes (e.g., 60)",
"minimum": 15
},
{
"type": "string",
"description": "Duration of the service as a text description (e.g., 'on demand')"
}
]
}
}
}
}
}
}

41
tests/ValidateServices.js Normal file
View File

@ -0,0 +1,41 @@
import Ajv from 'ajv';
import fs from 'fs';
import path from 'path';
const serviceSchema = JSON.parse(fs.readFileSync('./src/routes/sluzby/schema.json', 'utf-8'));
function validateFile(filePath) {
const ajv = new Ajv();
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
const validate = ajv.compile(serviceSchema);
const valid = validate(data);
if (!valid) {
throw new Error(`Invalid service data in ${filePath}: ${JSON.stringify(validate.errors)}`);
}
}
function scanDirectory(directory) {
const files = fs.readdirSync(directory);
for (const file of files) {
const filePath = path.join(directory, file);
const stat = fs.statSync(filePath);
if (stat.isDirectory()) {
scanDirectory(filePath);
} else if (path.extname(filePath) === '.json') {
validateFile(filePath);
}
}
}
export function validateServices() {
try {
scanDirectory('./src/content/services');
console.log('All services validated successfully!');
} catch (error) {
console.error(`Error validating services: ${error}`);
process.exit(1); // Exit with non-zero code to signal failure
}
}
validateServices();