Services OVERHAUL =>> using json with schemas and validators as database
This commit is contained in:
parent
15e7a32263
commit
449f67c2a0
18
package.json
18
package.json
|
@ -1,13 +1,15 @@
|
|||
{
|
||||
"name": "cosmeticstudio",
|
||||
"name": "kkosmetickysalon",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite dev --mode development",
|
||||
"build": "vite build",
|
||||
"build-dev": "vite build --mode development",
|
||||
"validate": "node ./tests/ValidateServices.js",
|
||||
"dev": "pnpm run validate && vite dev --mode development",
|
||||
"build": "pnpm run validate && vite build",
|
||||
"build-dev": "pnpm run validate && vite build --mode development",
|
||||
"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:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --plugin-search-dir . --check . && eslint .",
|
||||
|
@ -23,7 +25,8 @@
|
|||
"@fortawesome/fontawesome-free": "^6.5.1",
|
||||
"@sentry/sveltekit": "^7.107.0",
|
||||
"@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": {
|
||||
"@floating-ui/dom": "1.5.3",
|
||||
|
@ -53,6 +56,5 @@
|
|||
"vite": "^5.1.6",
|
||||
"vite-plugin-tailwind-purgecss": "^0.2.0",
|
||||
"vitest": "^0.32.4"
|
||||
},
|
||||
"type": "module"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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ě"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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')"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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();
|
Loading…
Reference in New Issue