Merge pull request 'wine-characteristics' (#38) from wine-characteristics into staging
Reviewed-on: #38
This commit is contained in:
commit
1598ee8b0b
@ -1,10 +1,11 @@
|
||||
import { ObjectId } from 'mongodb'
|
||||
import { RatingOptions } from '../types'
|
||||
|
||||
export class Review {
|
||||
constructor(
|
||||
public eventId: string, // foreign key referencing the nostrEvents collection
|
||||
public productId: string, // unique identifier for the product
|
||||
public rating: number, // numerical rating, e.g., 1-100
|
||||
public rating: number | RatingOptions, // numerical rating, e.g., 84-100 or NS (no score)
|
||||
public reviewText: string, // text content of the review
|
||||
public tastingNotes: string[], // array of tasting notes, e.g., flavours, aromas
|
||||
public id?: ObjectId // database object id
|
||||
|
@ -6,7 +6,12 @@ import {
|
||||
VintageOptions,
|
||||
StandardDrinks,
|
||||
WineRegion,
|
||||
WineVolume
|
||||
WineVolume,
|
||||
WineStyle,
|
||||
WhiteWineCharacteristic,
|
||||
AmberWineCharacteristic,
|
||||
RoseWineCharacteristic,
|
||||
RedWineCharacteristic
|
||||
} from '../types'
|
||||
import { Alpha2Code } from 'i18n-iso-countries'
|
||||
import { CurrencyCode } from 'currency-codes-ts/dist/types'
|
||||
@ -17,8 +22,13 @@ export class Wine {
|
||||
public productCodeUPC: string, // Product Code (https://en.wikipedia.org/wiki/Universal_Product_Code)
|
||||
public productCodeSKU: string, // Stock keeping unit (https://en.wikipedia.org/wiki/Stock_keeping_unit)
|
||||
public type: WineType, // numerical rating, e.g., 1-100
|
||||
public style: string, // bubbles+fizz, table, dessert, fortified, vermouth
|
||||
public characteristic: string, // light aromatic, textural, fruit forward, structural & savoury, powerful
|
||||
public style: WineStyle, // bubbles+fizz, table, dessert, fortified, vermouth
|
||||
public characteristics: (
|
||||
| WhiteWineCharacteristic
|
||||
| AmberWineCharacteristic
|
||||
| RoseWineCharacteristic
|
||||
| RedWineCharacteristic
|
||||
)[], // light aromatic, textural, fruit forward, structural & savoury, powerful
|
||||
public country: Alpha2Code, // two-letter country codes defined in ISO 3166-1 (https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2)
|
||||
public region: WineRegion, // appellation, village, sub-region, vineyard
|
||||
public name: string, // label
|
||||
|
@ -1,10 +1,10 @@
|
||||
export type CoffeeProcessingType =
|
||||
| 'de-caff'
|
||||
| 'honey'
|
||||
| 'semi-dry'
|
||||
| 'swiss water'
|
||||
| 'sundried'
|
||||
| 'washed'
|
||||
| 'De-caff'
|
||||
| 'Honey'
|
||||
| 'Semi-dry'
|
||||
| 'Swiss water'
|
||||
| 'Sundried'
|
||||
| 'Washed'
|
||||
|
||||
type CoffeeVarietyType = 'Robusta' | 'Arabica'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
export type Availability = 'in stock' | 'out of stock' | 'discontinued'
|
||||
export type Availability = 'In stock' | 'Out of stock' | 'Discontinued'
|
||||
|
||||
export type Ingredient =
|
||||
| 'Blanche'
|
||||
@ -62,11 +62,15 @@ export type Ingredient =
|
||||
| 'Walnut'
|
||||
|
||||
export enum VintageOptions {
|
||||
NV = 'nv',
|
||||
MV = 'mv'
|
||||
NV = 'NV',
|
||||
MV = 'MV'
|
||||
}
|
||||
|
||||
export interface StandardDrinks {
|
||||
'100ml': { AU: number; UK: number; US: number }
|
||||
bottle: { AU: number; UK: number; US: number }
|
||||
}
|
||||
|
||||
export enum RatingOptions {
|
||||
NoScore = 'NS'
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
export type SakeDesignation =
|
||||
| 'table'
|
||||
| 'pure'
|
||||
| 'blended'
|
||||
| 'mirin:new'
|
||||
| 'mirin:true'
|
||||
| 'mirin:salt'
|
||||
| 'Table'
|
||||
| 'Pure'
|
||||
| 'Blended'
|
||||
| 'Mirin:new'
|
||||
| 'Mirin:true'
|
||||
| 'Mirin:salt'
|
||||
|
||||
export type SakeStarter = 'Kimoto' | 'Sokujō' | 'Yamahai'
|
||||
|
@ -1,4 +1,4 @@
|
||||
export type SpiritType = 'white' | 'dark' | 'liqueurs'
|
||||
export type SpiritType = 'White' | 'Dark' | 'Liqueurs'
|
||||
|
||||
export type SpiritVariant =
|
||||
| 'Absinthe'
|
||||
@ -77,7 +77,7 @@ export interface WhiteSpiritKind {
|
||||
},
|
||||
'Plymouth'
|
||||
]
|
||||
Mezcal: [{ Joven: ['espadín', 'tepeztate', 'Tequilana (blue)', 'tobalá'] }]
|
||||
Mezcal: [{ Joven: ['Espadín', 'Tepeztate', 'Tequilana (blue)', 'Tobalá'] }]
|
||||
Rum: ['Blanco', 'Cachaça', 'Platino', 'Agricole']
|
||||
'Eau de Vie': [
|
||||
'Apple (Pomme)',
|
||||
|
@ -1,5 +1,5 @@
|
||||
export enum UserRole {
|
||||
User = 'user',
|
||||
Reviewer = 'reviewer',
|
||||
Producer = 'producer'
|
||||
User = 'User',
|
||||
Reviewer = 'Reviewer',
|
||||
Producer = 'Producer'
|
||||
}
|
||||
|
@ -1,20 +1,53 @@
|
||||
export enum WineType {
|
||||
White = 'white',
|
||||
Amber = 'amber',
|
||||
Rose = 'rose',
|
||||
Red = 'red'
|
||||
White = 'White',
|
||||
Amber = 'Amber',
|
||||
Rose = 'Rose',
|
||||
Red = 'Red'
|
||||
}
|
||||
|
||||
export enum WhiteWineCharacteristic {
|
||||
LightAromatic = 'Light Aromatic',
|
||||
TexturalAndSavory = 'Textural and Savory',
|
||||
RichAndFruitForward = 'Rich and Fruit Forward'
|
||||
}
|
||||
|
||||
export enum AmberWineCharacteristic {
|
||||
TexturalAndAromatic = 'Textural and Aromatic',
|
||||
StructuralAndSavory = 'Structural and Savory',
|
||||
PowerAndPresence = 'Power and Presence'
|
||||
}
|
||||
|
||||
export enum RoseWineCharacteristic {
|
||||
LightAndFruitForward = 'Light and Fruit Forward',
|
||||
TexturalAndSavory = 'Textural and Savory',
|
||||
StructuralAndAromatic = 'Structural and Aromatic'
|
||||
}
|
||||
|
||||
export enum RedWineCharacteristic {
|
||||
LightAndFruitForward = 'Light and Fruit Forward',
|
||||
StructuralAndAromatic = 'Structural and Aromatic',
|
||||
TexturalAndSavory = 'Textural and Savory',
|
||||
PowerAndPresence = 'Power and Presence'
|
||||
}
|
||||
|
||||
export enum WineStyle {
|
||||
BubblesAndFizz = 'Bubbles + Fizz',
|
||||
Table = 'Table',
|
||||
Dessert = 'Dessert',
|
||||
Fortified = 'Fortified',
|
||||
Vermouth = 'Vermouth'
|
||||
}
|
||||
|
||||
export enum Viticulture {
|
||||
Biodynamic = 'biodynamic',
|
||||
Organic = 'organic',
|
||||
Conventional = 'conventional'
|
||||
Biodynamic = 'Biodynamic',
|
||||
Organic = 'Organic',
|
||||
Conventional = 'Conventional'
|
||||
}
|
||||
|
||||
export enum BottleClosure {
|
||||
Cork = 'cork',
|
||||
CrownSeal = 'crown-seal',
|
||||
Screwcap = 'screwcap'
|
||||
Cork = 'Cork',
|
||||
CrownSeal = 'Crown-seal',
|
||||
Screwcap = 'Screwcap'
|
||||
}
|
||||
|
||||
export interface WineRegion {
|
||||
|
@ -1,10 +1,16 @@
|
||||
import Joi from 'joi'
|
||||
import { RatingOptions } from '../../types'
|
||||
|
||||
export const reviewValidation = (data: unknown): Joi.ValidationResult =>
|
||||
Joi.object({
|
||||
eventId: Joi.string().required(),
|
||||
productId: Joi.string().required(),
|
||||
rating: Joi.number().required(),
|
||||
rating: Joi.alternatives()
|
||||
.try(
|
||||
Joi.string().valid(...Object.values(RatingOptions)),
|
||||
Joi.number().min(84).max(100)
|
||||
)
|
||||
.required(),
|
||||
reviewText: Joi.string().required(),
|
||||
tastingNotes: Joi.array().items(Joi.string())
|
||||
}).validate(data)
|
||||
|
@ -5,7 +5,12 @@ import {
|
||||
BottleClosure,
|
||||
Viticulture,
|
||||
WineRegion,
|
||||
WineVolume
|
||||
WineVolume,
|
||||
WineStyle,
|
||||
WhiteWineCharacteristic,
|
||||
AmberWineCharacteristic,
|
||||
RoseWineCharacteristic,
|
||||
RedWineCharacteristic
|
||||
} from '../../types'
|
||||
import { wineRegionsMap, isObject } from '../'
|
||||
|
||||
@ -17,8 +22,80 @@ export const wineValidation = (data: unknown): Joi.ValidationResult =>
|
||||
type: Joi.string()
|
||||
.valid(...Object.values(WineType))
|
||||
.required(),
|
||||
style: Joi.string().required(),
|
||||
characteristic: Joi.string().required(),
|
||||
style: Joi.string()
|
||||
.valid(...Object.values(WineStyle))
|
||||
.required(),
|
||||
characteristic: Joi.array()
|
||||
.items(Joi.string())
|
||||
.custom((value: string[], helper) => {
|
||||
// return if no value
|
||||
if (!value) {
|
||||
return value
|
||||
}
|
||||
// return if no state ancestors
|
||||
if (!helper.state.ancestors) {
|
||||
return value
|
||||
}
|
||||
|
||||
const wineType: WineType = helper.state.ancestors[0].type
|
||||
|
||||
// return if no wineType
|
||||
if (!wineType) {
|
||||
return value
|
||||
}
|
||||
|
||||
let options: string[] = []
|
||||
|
||||
switch (wineType) {
|
||||
case WineType.White:
|
||||
{
|
||||
options = Object.values(WhiteWineCharacteristic)
|
||||
}
|
||||
|
||||
break
|
||||
case WineType.Amber:
|
||||
{
|
||||
options = Object.values(AmberWineCharacteristic)
|
||||
}
|
||||
|
||||
break
|
||||
case WineType.Rose:
|
||||
{
|
||||
options = Object.values(RoseWineCharacteristic)
|
||||
}
|
||||
|
||||
break
|
||||
case WineType.Red:
|
||||
{
|
||||
options = Object.values(RedWineCharacteristic)
|
||||
}
|
||||
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if (!options.length) {
|
||||
return helper.message({
|
||||
custom: Joi.expression(
|
||||
`no characteristics found for provided type of wine`
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
for (const characteristic of value) {
|
||||
if (!options.includes(characteristic)) {
|
||||
return helper.message({
|
||||
custom: Joi.expression(
|
||||
`"${characteristic}" is not a valid characteristic for "${wineType}" wine. Valid options are [${options.map((option) => `"${option}"`).join(', ')}]`
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return value
|
||||
}),
|
||||
country: Joi.string().length(2),
|
||||
region: Joi.alternatives()
|
||||
.try(
|
||||
|
Loading…
x
Reference in New Issue
Block a user