Rewriting database and API to transform to a ticket shop

This commit is contained in:
2024-09-26 11:04:27 +02:00
parent 080610cd7e
commit 787c5a61e5
88 changed files with 1040 additions and 751 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,43 @@
{
"data": [
{
"id": 0,
"name": "Red Hot Chili Peppers",
"foundingYear": 1983,
"descriptionEn": "The Red Hot Chili Peppers are an American rock band formed in Los Angeles in 1983, comprising vocalist Anthony Kiedis, bassist Flea, drummer Chad Smith, and guitarist John Frusciante. Their music incorporates elements of alternative rock, funk, punk rock, hard rock, hip hop, and psychedelic rock. Their eclectic range has influenced genres such as funk metal, rap metal, rap rock, and nu metal. With over 120 million records sold worldwide, the Red Hot Chili Peppers are one of the top-selling bands of all time.",
"descriptionDe": "Red Hot Chili Peppers (Abkürzung: RHCP) ist eine 1983 gegründete US-amerikanische Funk- und Alternative-Rockband. Sie zählt zu den kommerziell erfolgreichsten Vertretern des Crossover. Ihr Album Blood Sugar Sex Magik gilt als eines der bedeutendsten dieses Genres.",
"images": [ "red-hot-chili-peppers.jpg" ],
"logo": "red-hot-chili-peppers-logo.png",
"genreId": 0,
"members": [
{
"name": "Anthony Kiedis",
"bandId": 0,
"image": "anthony-kiedis.jpg"
},
{
"name": "Flea",
"bandId": 0,
"image": "flea.jpg"
},
{
"name": "Chad Smith",
"bandId": 0,
"image": "chad-smith.jpg"
},
{
"name": "John Frusciante",
"bandId": 0,
"image": "john-frusciante.jpg"
}
],
"ratings": [
{
"accountId": 0,
"rating": 5,
"bandId": 0
}
]
}
]
}

View File

@@ -1,40 +0,0 @@
{
"data": [
{
"id": 0,
"name": "Lenovo"
},
{
"id": 1,
"name": "Puma"
},
{
"id": 2,
"name": "George Orwell"
},
{
"id": 3,
"name": "Aldous Huxley"
},
{
"id": 4,
"name": "Dell"
},
{
"id": 5,
"name": "Fender"
},
{
"id": 6,
"name": "ESP"
},
{
"id": 7,
"name": "Pearl"
},
{
"id": 8,
"name": "Apple"
}
]
}

View File

@@ -0,0 +1,8 @@
{
"data": [
{
"id": 0,
"name": "Funk rock"
}
]
}

View File

@@ -0,0 +1,10 @@
{
"data": [
{
"id": 0,
"name": "Swiss Life Hall",
"address": "Ferdinand-Wilhlem-Fricke-Weg 8, 30169 Hannover",
"image": "swiss-life-hall.jpg"
}
]
}

View File

@@ -5,28 +5,7 @@
"orderId": 0, "orderId": 0,
"productId": 0, "productId": 0,
"quantity": 2, "quantity": 2,
"orderPrice": 1769.99 "orderPrice": 184
},
{
"id": 1,
"orderId": 1,
"productId": 6,
"quantity": 1,
"orderPrice": 899.99
},
{
"id": 2,
"orderId": 2,
"productId": 3,
"quantity": 3,
"orderPrice": 9.99
},
{
"id": 3,
"orderId": 2,
"productId": 2,
"quantity": 1,
"orderPrice": 14.99
} }
] ]
} }

View File

@@ -1,315 +0,0 @@
{
"data": [
{
"id": 0,
"brandId": 0,
"name": "Thinkpad T14s Gen 4",
"price": 1769.99,
"categoryId": 1,
"discount": 10,
"rating": 4.6,
"description": "Mehr Leistung und deutlich längere Akkulaufzeiten: Mit dem AMD Ryzen-Prozessor und dem matten IPS-Display ist das Lenovo ThinkPad T14s G4 noch besser und gehört zu den besten Business-Laptops auf dem Markt. - Notebookcheck.com",
"specs": [
"Prozessor: AMD Ryzen 7 Pro 7840U",
"Betriebssystem: Windows 11 Pro (64 Bit)",
"Grafik: Integrierte Grafik",
"Hauptspeicher: 32 GB LPDDR5X-6400MHz (1 x 32 GB verlötet)",
"Massenspeicher: 512 GB SSD, M.2 2280, PCIe 4.0, TLC, Opal",
"Displaytyp: 14 WUXGA (1920 x 1200), IPS, matt, Non-Touch, 100% sRGB, 400 cd/m², 60 Hz, low power-ausführung",
"Gewicht: Ab 1,25 kg"
],
"images": [
"thinkpad-t14s-1.avif",
"thinkpad-t14s-2.avif",
"thinkpad-t14s-3.avif",
"thinkpad-t14s-4.avif",
"thinkpad-t14s-5.avif",
"thinkpad-t14s-6.avif",
"thinkpad-t14s-7.avif"
],
"inStock": 5,
"offered": true
},
{
"id": 1,
"brandId": 1,
"name": "Men's T-Shirt Black",
"price": 14.99,
"categoryId": 3,
"discount": 0,
"rating": 3.8,
"description": "On the court at home. With individual football clothing from Puma. - Forever Faster doesn't just mean speed. It means strength, stamina, means to want to get better every day... And this means: It's about you. Our mission is to make you fit exactly as you want to be so you can achieve every goal as fast as possible.",
"specs": [
"Material composition: 100% Cotton",
"Care instructions: Machine Wash",
"Closure type: Pull On",
"Neck style: Round Neck",
"Country of origin: China"
],
"images": [
"puma-t-shirt-men-1.jpg",
"puma-t-shirt-men-2.jpg",
"puma-t-shirt-men-3.jpg",
"puma-t-shirt-men-4.jpg",
"puma-t-shirt-men-5.jpg"
],
"inStock": 30,
"offered": true
},
{
"id": 2,
"brandId": 1,
"name": "Woman's Shirt",
"price": 14.99,
"categoryId": 3,
"discount": 0,
"rating": 3.9,
"description": "",
"specs": [
"Womens T-shirt for leisure and sport",
"Black sportswear by Puma",
"T-Shirt ESS Logo Tee Puma Black",
"Puma sports products are designed so that you can enjoy your favourite sport without having to worry about anything other than achieving your best",
"Sportswear made from high-quality materials for any sporting activity"
],
"images": [
"puma-t-shirt-woman-1.jpg",
"puma-t-shirt-woman-2.jpg",
"puma-t-shirt-woman-3.jpg",
"puma-t-shirt-woman-4.jpg",
"puma-t-shirt-woman-5.jpg",
"puma-t-shirt-woman-6.jpg"
],
"inStock": 30,
"offered": true
},
{
"id": 3,
"brandId": 2,
"name": "1984",
"price": 9.99,
"categoryId": 4,
"discount": 0,
"rating": 4.9,
"description": "London, 1984: Winston Smith, Geschichtsfälscher im Staatsdienst, verliebt sich in die schöne und geheimnisvolle Julia. Gemeinsam beginnen sie, die totalitäre Welt infrage zu stellen, als Teil derer sie bisher funktioniert haben. Doch bereits ihre Gedanken sind Verbrechen, und der Große Bruder richtet seinen stets wachsamen Blick auf jeden potenziellen Dissidenten. George Orwells Vision eines totalitären Staats, in dem Cyberüberwachung, Geschichtsrevisionismus und Gedankenpolizei den Alltag gläserner Bürger bestimmen, hat wie keine andere Dystopie bis heute nur an Brisanz gewonnen.",
"specs": [
"Erscheinungsdatum: 18. Januar 2021",
"Sprache: deutsch",
"Seitenanzahl: 399",
"Autor/Autorin: George Orwell",
"Übersetzung: Jan Strümpel",
"Verlag/Hersteller: Anaconda Verlag",
"Originaltitel: 1984",
"Originalsprache: englisch",
"Produktart: gebunden",
"Gewicht: 412 g",
"Größe (L/B/H): 192/131/38 mm",
"ISBN: 9783730609767"
],
"images": [
"1984-1.webp",
"1984-2.webp",
"1984-3.webp"
],
"inStock": 30,
"offered": true
},
{
"id": 4,
"brandId": 3,
"name": "Brave New World",
"price": 10.49,
"categoryId": 4,
"discount": 0,
"rating": 4.4,
"description": "Brave New World beschreibt eine genormte Gesellschaft, in der Föten genetisch manipuliert und Menschen konditioniert werden. Ziel des Staates ist Zufriedenheit und Stabilität, und dies wird durch Gleichheit, Drogen und Propaganda erreicht. Gott und Religion...",
"specs": [
"Erscheinungsdatum: 07. Juni 2011",
"Sprache: englisch",
"Reihe: Vintage Classics",
"Autor/Autorin: Aldous Huxley",
"Verlag/Hersteller: Random House UK Ltd",
"Produktart: kartoniert",
"Gewicht: 208 g",
"Größe (L/B/H): 198/131/22 mm",
"Sonstiges: B-format paperback",
"ISBN: 9780099518471"
],
"images": [
"brave-new-world-1.jpg",
"brave-new-world-2.jpg"
],
"inStock": 30,
"offered": true
},
{
"id": 5,
"brandId": 4,
"name": "XPS 8960 Desktop",
"price": 1640.26,
"categoryId": 1,
"discount": 0,
"rating": 4.1,
"description": "Mit dem XPS-Desktop-PC profitieren Sie von herausragender Performance und Erweiterbarkeit.",
"specs": [
"Intel Core i7-13700-Prozessor der 13. Generation (16 Kerne, 24 MB Cache, 2,1 GHz 5,1 GHz)",
"NVIDIA GeForce RTX 4060, 8 GB GDDR6 Grafikkarte",
"1-TB-M.2-PCIe-NVMe-SSD",
"16 GB, 2 x 8 GB, DDR5, 4800 MHz; 64 GB (zusätzlicher Speicher separat erhältlich)"
],
"images": [
"dell-xps-desktop-1.jpg",
"dell-xps-desktop-2.jpg",
"dell-xps-desktop-3.jpg",
"dell-xps-desktop-4.jpg",
"dell-xps-desktop-5.jpg",
"dell-xps-desktop-6.jpg"
],
"inStock": 10,
"offered": true
},
{
"id": 6,
"brandId": 5,
"name": "Player II Jazz Bass RW 3TS",
"price": 899.99,
"categoryId": 5,
"discount": 5,
"rating": 4.8,
"description": "The Fender Player II JazzBass RW 3TS 3-Color Sunburst relies on great features that stand out in terms of comfort, playability and look, as well as providing all the advantages for a wide variety of genres. Whether dynamic bass lines or lush rock riffs: the Fender Player II Jazz Bass is a versatile E-Bass that is not only perfect for practice or studio sessions, but also functions as an assertive bass carpet in band contexts and live mixes. The robust alder body has a classic 3-color Sunburst-Finish finish and shines with easy handling and a comfortable grip - whether sitting or standing. The maple neck with a modern 'C' neck profile is fitted with a rosewood fingerboard, which is equipped with 20 medium jumbo frets and a fingerboard radius of 9.5', making it easy to use a wide variety of bass techniques and enabling quick fretting and precise riffs to be tackled cleanly.",
"specs": [
"Body: Alder",
"Bolt-on neck: Maple",
"Fingerboard: Rosewood",
"Fingerboard inlays: white dots",
"Nut: Synthetic bone",
"Neck profile: Modern 'C'",
"Nut width: 38.1 mm (1.5')",
"Fingerboard radius: 241 mm (9.5')",
"Scale: 864 mm (34')",
"20 Medium jumbo frets",
"Pickups: 2 Player Series Jazz Bass Alnico 5 single coils",
"Controls: 2 volume and 1 tone",
"Pickguard: 3-ply parchement",
"Standard bridge with 4 saddles",
"Open standard machine heads",
"Nickel/chrome hardware",
"Strings: Fender USA 7250M Nickel-plated steel .045 - .105",
"Colour: 3-Colour Sunburst"
],
"images": [
"fender-player-ii-jazz-bass-rw-3ts-1.jpg",
"fender-player-ii-jazz-bass-rw-3ts-2.jpg",
"fender-player-ii-jazz-bass-rw-3ts-3.jpg",
"fender-player-ii-jazz-bass-rw-3ts-4.jpg",
"fender-player-ii-jazz-bass-rw-3ts-5.jpg"
],
"inStock": 15,
"offered": true
},
{
"id": 7,
"brandId": 6,
"name": "LTD Iron Cross SW",
"price": 2999.00,
"categoryId": 5,
"discount": 0,
"rating": 4.6,
"description": "The LTD Iron Cross is a Signature Series model of James Hetfield, the frontman of Metallica and one of the world's most highly respected rhythm guitar players in any genre. The Iron Cross is based on James' personal custom instrument design, and features set-neck construction of a mahogany body with maple cap, and a three-piece mahogany neck with ebony fingerboard and 22 extra-jumbo frets with an Iron Cross inlay at the 12th fret. The LTD Iron Cross is powered by James' own EMG JH SET active pickups, and includes a TonePros locking TOM bridge and tailpiece. Available in Snow White finish with black stripe graphic and iron cross fixture.",
"specs": [
"James Hetfield Signature Model",
"Mahogany body",
"Maple top",
"Set-in mahogany neck",
"Neck profile: Thin U",
"Makassar ebony fretboard",
"Fretboard radius: 350 mm",
"22 Extra jumbo frets",
"Nut width: 42 mm",
"Scale: 629 mm",
"Black pickguard",
"Pickups: Active EMG JH SET (bridge) and Active EMG JH SET (neck)",
"2 x Volume and 1 x tone control",
"3-Way switch",
"Tonepros Locking TOM bridge and tailpiece",
"Black hardware",
"LTD locking machine heads",
"Original strings: D'Addario XL110 (.010-.046)",
"Colour: Snow White With Black Stripes",
"Includes case"
],
"images": [
"esp-lts-iron-cross-sw-1.jpg",
"esp-lts-iron-cross-sw-2.jpg",
"esp-lts-iron-cross-sw-3.jpg",
"esp-lts-iron-cross-sw-4.jpg",
"esp-lts-iron-cross-sw-5.jpg",
"esp-lts-iron-cross-sw-6.jpg"
],
"inStock": 0,
"offered": true
},
{
"id": 8,
"brandId": 7,
"name": "Decade Maple Standard D. Black",
"price": 1444.00,
"categoryId": 5,
"discount": 0,
"rating": 4.7,
"description": "Pearl präsentiert das erste Drumset mit 6-lagigen Ahorn Kesseln, die mit der speziellen Pearl Superior Shell Technology hergestellt sind und preislich in der unteren Mittelklasse liegen. 10 Jahre Entwicklung machen es möglich, ein professionelles und absolut bühnentaugliches Drumset mit genialer Stickdefinition, definierten Höhen und voluminösem Bass zu einem unschlagbaren Preis anzubieten. Die Decade Sets sind mit einem 5-teiligen Hardwareset aus der Pearl 800er Serie ausgestattet.",
"specs": [
"Decade Maple Series",
"Standard version",
"DMP925S/C-227",
"Matte lacquer finish shells",
"Chrome shell hardware",
"Shells made of thin 6-ply maple with 5.4 mm wall thickness",
"1.6 mm triple-flanged hoops",
"OptiLoc tom mounting system",
"Remo Ambassador UT and Remo Powerstroke 3 (kick drum) heads",
"Kick drum resonant head with sound hole",
"Highly responsive set with great tonal and dynamic range",
"Colour: Satin Black Slate (-227)",
"Kick drum damping cushion included"
],
"images": [
"pearl-decade-maple-standard-black-1.jpg",
"pearl-decade-maple-standard-black-2.jpg",
"pearl-decade-maple-standard-black-3.jpg",
"pearl-decade-maple-standard-black-4.jpg",
"pearl-decade-maple-standard-black-5.jpg",
"pearl-decade-maple-standard-black-6.jpg"
],
"inStock": 4,
"offered": true
},
{
"id": 9,
"brandId": 8,
"name": "MacBook Air 13.6 Zoll M3",
"price": 1759.00,
"categoryId": 1,
"discount": 15,
"rating": 4.3,
"description": "",
"specs": [
"SUPERLEICHT. M3GAPOWER. Das ultraschnelle MacBook Air mit dem M3 Chip ist ein supermobiler Laptop, mit dem du so schnell arbeitest, wie du spielst.",
"MOBILES DESIGN Superleicht und 11,5 mm dünn, sodass du dein MacBook Air überallhin mitnehmen kannst.",
"MEHR SCHNELLER ERLEDIGEN Mit der leistungsstarken 8-Core CPU und der bis zu 10-Core GPU des Apple M3 Chip läuft alles flüssig.",
"BIS ZU 18 STUNDEN BATTERIELAUFZEIT (1) Fantastische Batterielaufzeit für den ganzen Tag. Da kannst du dein Netzteil zu Hause lassen.",
"EIN BRILLANTES DISPLAY Das 13,6 Liquid Retina Display (2) unterstützt eine Milliarde Farben.",
"GUT AUSSEHEN, GROSSARTIG KLINGEN Mit einer 1080p HD Kamera, drei Mikrofonen und vier Lautsprechern mit 3D Audio sieht alles großartig aus und klingt auch so."
],
"images": [
"macbook-air-1.avif",
"macbook-air-2.avif",
"macbook-air-3.avif",
"macbook-air-4.avif",
"macbook-air-5.avif"
],
"inStock": 18,
"offered": false
}
]
}

View File

@@ -0,0 +1,14 @@
{
"data": [
{
"id": 0,
"name": "Unlimited Love Tour",
"bandId": 0,
"date": "2024-12-03",
"price": 92,
"inStock": 230,
"offered": true,
"locationId": 0
}
]
}

View File

@@ -1,16 +1,19 @@
import { Sequelize } from "sequelize-typescript" import { Sequelize } from "sequelize-typescript"
// Models // Models
import { Category } from "./models/category.model"
import { Order } from "./models/order.model" import { Order } from "./models/order.model"
import { OrderItem } from "./models/orderItem.model" import { OrderItem } from "./models/orderItem.model"
import { Product } from "./models/product.model"
import { Account } from "./models/account.model" import { Account } from "./models/account.model"
import { prepopulateDatabase } from "./scripts/databaseHelper" import { prepopulateDatabase } from "./scripts/databaseHelper"
import { Address } from "./models/address.model" import { Address } from "./models/address.model"
import { Payment } from "./models/payment.model" import { Payment } from "./models/payment.model"
import { AccountRole } from "./models/accountRole.model" import { AccountRole } from "./models/accountRole.model"
import { Brand } from "./models/brand.model" import { Genre } from "./models/genre.model"
import { Location } from "./models/location.model"
import { Band } from "./models/band.model"
import { Show } from "./models/show.model"
import { Member } from "./models/member.model"
import { Rating } from "./models/rating.model"
const dbName = "database" const dbName = "database"
const dbUser = "root" const dbUser = "root"
@@ -23,7 +26,7 @@ export const sequelize = new Sequelize({
username: dbUser, username: dbUser,
password: dbPassword, password: dbPassword,
storage: "database.sqlite", storage: "database.sqlite",
models: [ Address, Payment, AccountRole, Account, Category, Brand, Product, Order, OrderItem ] models: [ Genre, Location, AccountRole, Account, Payment, Address, Order, Band, Show, Member, Rating, OrderItem ]
}) })
export function startDatabase() { export function startDatabase() {
@@ -32,7 +35,7 @@ export function startDatabase() {
.then(() => { .then(() => {
console.log("Database & tables created!") console.log("Database & tables created!")
//prepopulateDatabase() prepopulateDatabase()
console.log("Database prepopulated!") console.log("Database prepopulated!")
}) })
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 265 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.3 KiB

View File

@@ -3,6 +3,7 @@ import { Order } from './order.model';
import { Address } from './address.model'; import { Address } from './address.model';
import { Payment } from './payment.model'; import { Payment } from './payment.model';
import { AccountRole } from './accountRole.model'; import { AccountRole } from './accountRole.model';
import { Rating } from './rating.model';
@Table({ timestamps: false }) @Table({ timestamps: false })
export class Account extends Model { export class Account extends Model {
@@ -38,6 +39,9 @@ export class Account extends Model {
@HasMany(() => Order) @HasMany(() => Order)
orders: Order[] orders: Order[]
@HasMany(() => Rating)
ratings: Rating[]
@BelongsTo(() => AccountRole) @BelongsTo(() => AccountRole)
accountRole: AccountRole accountRole: AccountRole
} }

View File

@@ -0,0 +1,49 @@
import { BelongsTo, Column, DataType, ForeignKey, HasMany, Model, Table } from "sequelize-typescript";
import { Member } from "./member.model";
import { Genre } from "./genre.model";
import { Rating } from "./rating.model";
@Table({ timestamps: false })
export class Band extends Model {
@Column
name: String
@Column
foundingYear: Number
@Column
descriptionEn: String
@Column
descriptionDe: String
@Column({
type: DataType.STRING,
get(): Array<string> {
return this.getDataValue('images').split(';')
},
set(value: Array<string>) {
this.setDataValue('images', value.join(';'))
}
})
images: Array<String>
@Column
logo: String
@ForeignKey(() => Genre)
@Column
genreId: Number
// Relations
@HasMany(() => Member)
members: Member[]
@HasMany(() => Rating)
ratings: Rating[]
@BelongsTo(() => Genre)
genre: Genre
}

View File

@@ -1,14 +0,0 @@
import { Column, HasMany, Model, Table } from "sequelize-typescript";
import { Product } from "./product.model";
@Table({ timestamps: false })
export class Brand extends Model {
@Column
name: string
// Relations
@HasMany(() => Product)
products: Product[]
}

View File

@@ -1,15 +0,0 @@
import { Table, Column, Model, BelongsTo, ForeignKey, HasMany, Unique } from 'sequelize-typescript';
import { Product } from './product.model';
@Table({ timestamps: false })
export class Category extends Model {
@Unique
@Column
name: string
@Column
icon: string
@HasMany(() => Product)
product: Product
}

View File

@@ -0,0 +1,14 @@
import { Column, HasMany, Model, Table } from "sequelize-typescript";
import { Band } from "./band.model";
@Table({ timestamps: false })
export class Genre extends Model {
@Column
name: String
// Relations
@HasMany(() => Band)
bands: Band[]
}

View File

@@ -0,0 +1,13 @@
import { Column, Model, Table } from "sequelize-typescript";
@Table({ timestamps: false })
export class Location extends Model {
@Column
name: String
@Column
address: String
@Column
image: String
}

View File

@@ -0,0 +1,21 @@
import { BelongsTo, Column, ForeignKey, Model, Table } from "sequelize-typescript";
import { Band } from "./band.model";
@Table({ timestamps: false })
export class Member extends Model {
@Column
name: String
@ForeignKey(() => Band)
@Column
bandId: Number
@Column
image: String
// Relations
@BelongsTo(() => Band)
bands: Band[]
}

View File

@@ -1,5 +1,5 @@
import { Model, BelongsTo, Column, ForeignKey, HasMany, HasOne, Table } from "sequelize-typescript"; import { Model, BelongsTo, Column, ForeignKey, HasMany, HasOne, Table } from "sequelize-typescript";
import { Product } from "./product.model"; import { Show } from "./show.model";
import { Order } from "./order.model"; import { Order } from "./order.model";
@Table({ timestamps: false }) @Table({ timestamps: false })
@@ -15,7 +15,7 @@ export class OrderItem extends Model {
orderPrice: number orderPrice: number
@Column @Column
@ForeignKey(() => Product) @ForeignKey(() => Show)
productId: number productId: number
@@ -23,6 +23,6 @@ export class OrderItem extends Model {
@BelongsTo(() => Order) @BelongsTo(() => Order)
order: Order order: Order
@BelongsTo(() => Product) @BelongsTo(() => Show)
product: Product product: Show
} }

View File

@@ -1,70 +0,0 @@
import { Table, Column, Model, ForeignKey, BelongsTo, BelongsToMany, HasMany, DataType } from 'sequelize-typescript';
import { Category } from './category.model';
import { OrderItem } from './orderItem.model';
import { Brand } from './brand.model';
@Table({ timestamps: false })
export class Product extends Model {
@Column
@ForeignKey(() => Category)
categoryId: number
@ForeignKey(() => Brand)
@Column
brandId: number
@Column
name: string
@Column
description: string
@Column
price: number
@Column
discount: number
@Column
rating: number
@Column
inStock: number
@Column
offered: boolean
@Column({
type: DataType.STRING,
get(): Array<string> {
return this.getDataValue('specs').split(';')
},
set(value: Array<string>) {
this.setDataValue('specs', value.join(';'))
}
})
specs: Array<string>
@Column({
type: DataType.STRING,
get(): Array<string> {
return this.getDataValue('images').split(';')
},
set(value: Array<string>) {
this.setDataValue('images', value.join(';'))
}
})
images: Array<string>
// Relations
@BelongsTo(() => Category)
category: Category
@BelongsTo(() => Brand)
brand: Brand
@HasMany(() => OrderItem)
orders: OrderItem[]
}

View File

@@ -0,0 +1,27 @@
import { BelongsTo, Column, ForeignKey, Model, Table } from "sequelize-typescript";
import { Account } from "./account.model";
import { Band } from "./band.model";
@Table({ timestamps: false })
export class Rating extends Model {
@ForeignKey(() => Account)
@Column
accountId: Number
@Column
rating: Number
@ForeignKey(() => Band)
@Column
bandId: Number
// Relations
@BelongsTo(() => Account)
account: Account
@BelongsTo(() => Band)
band: Band
}

View File

@@ -0,0 +1,37 @@
import { BelongsTo, Column, ForeignKey, Model, Table } from "sequelize-typescript";
import { Band } from "./band.model";
import { Location } from "./location.model";
@Table({ timestamps: false })
export class Show extends Model {
@Column
name: String
@ForeignKey(() => Band)
bandId: Number
@Column
date: String
@Column
price: Number
@Column
inStock: Number
@Column
offered: Boolean
@ForeignKey(() => Location)
@Column
locationId: Number
// Relations
@BelongsTo(() => Band)
band: Band
@BelongsTo(() => Location)
location: Location
}

View File

@@ -0,0 +1,16 @@
import { Member } from "../models/member.model";
import { Band } from "../models/band.model";
import { Request, Response, Router } from "express";
import { Rating } from "../models/rating.model";
import { Genre } from "../models/genre.model";
export const band = Router()
band.get("/", (req: Request, res: Response) => {
Band.findAll({
include: [ Member, Rating, Genre ]
})
.then(bands => {
res.status(200).json(bands)
})
})

View File

@@ -1,12 +0,0 @@
import { Brand } from "../models/brand.model"
import { Request, Router, Response } from "express"
export const brand = Router()
// Get all brands
brand.get("/", (req: Request, res: Response) => {
Brand.findAll()
.then(brands => {
res.status(200).json(brands)
})
})

View File

@@ -1,42 +0,0 @@
import { Router, Request, Response, NextFunction } from "express";
import { Category } from "../models/category.model";
export const category = Router()
// Get all categories
category.get("/", (req: Request, res: Response, next: NextFunction) => {
Category.findAll()
.then(categories => {
res.status(200).json(categories)
})
})
// Add new category
category.post("/", (req: Request, res: Response, next: NextFunction) => {
Category.create(req.body)
.then(category => {
res.status(201).json(category)
})
.catch(error => {
res.status(400).json({
code: 400,
message: error
})
})
})
// Delete category
category.delete("/:id", (req: Request, res: Response, next: NextFunction) => {
Category.destroy({
where: { id: req.params.id }
})
.then(category => {
res.status(200).json(category)
})
.catch(error => {
res.status(400).json({
code: 400,
message: error
})
})
})

View File

@@ -0,0 +1,11 @@
import { Genre } from "../models/genre.model";
import { Request, Response, Router } from "express";
export const genre = Router()
genre.get("/", (req: Request, res: Response) => {
Genre.findAll()
.then(genres => {
res.status(200).json(genres)
})
})

View File

@@ -0,0 +1,11 @@
import { Location } from "../models/location.model";
import { Request, Response, Router } from "express";
export const location = Router()
location.get("/", (req: Request, res: Response) => {
Location.findAll()
.then(locations => {
res.status(200).json(locations)
})
})

View File

@@ -1,11 +1,11 @@
import { Router, Request, Response } from "express"; import { Router, Request, Response } from "express";
import { Order } from "../models/order.model"; import { Order } from "../models/order.model";
import { Product } from "../models/product.model"; import { Show } from "../models/show.model";
import { OrderItem } from "../models/orderItem.model"; import { OrderItem } from "../models/orderItem.model";
import { Brand } from "../models/brand.model";
import { Category } from "../models/category.model";
import { Payment } from "../models/payment.model"; import { Payment } from "../models/payment.model";
import { Address } from "../models/address.model"; import { Address } from "../models/address.model";
import { Band } from "../models/band.model";
import { Location } from "../models/location.model";
export const order = Router() export const order = Router()
@@ -18,8 +18,8 @@ order.get("/:id", (req: Request, res: Response) => {
model: OrderItem, model: OrderItem,
include: [ include: [
{ {
model: Product, model: Show,
include: [ Brand, Category ], include: [ Band, Location ],
attributes: { attributes: {
exclude: [ exclude: [
"categoryId", "categoryId",
@@ -50,7 +50,7 @@ order.post("/", (req: Request, res: Response) => {
productId: orderItem.productId productId: orderItem.productId
}) })
Product.decrement( Show.decrement(
"inStock", "inStock",
{ {
by: orderItem.quantity, by: orderItem.quantity,

View File

@@ -1,71 +0,0 @@
import { Router, Request, Response, NextFunction } from "express";
import { Product } from "../models/product.model";
import { Category } from "../models/category.model";
import { Brand } from "../models/brand.model";
export const product = Router()
// Get all products
product.get("/", (req: Request, res: Response) => {
Product.findAll({
include: [ Category, Brand ],
attributes: {
exclude: [
"categoryId",
"brandId"
]
}
})
.then(products => {
res.status(200).json(products)
})
})
// Get a product by id
product.get("/:productId", (req: Request, res: Response) => {
Product.findByPk(
req.params.productId,
{
include: [ Category, Brand ],
attributes: {
exclude: [
"categoryId",
"brandId"
]
}
}
)
.then(product => {
res.status(200).json(product)
})
})
// Add a new product
product.post("/", (req: Request, res: Response) => {
Product.create(req.body)
.then(product => {
res.status(201).json(product)
})
.catch(error => {
res.status(400).json({
code: 400,
message: error
})
})
})
// Remove a product
product.delete("/:id", (req: Request, res: Response) => {
Product.destroy({
where: { id: req.params.id }
})
.then(product => {
res.status(200).json(product)
})
.catch(error => {
res.status(400).json({
code: 400,
message: error
})
})
})

View File

@@ -0,0 +1,11 @@
import { Show } from "../models/show.model";
import { Request, Response, Router } from "express";
export const show = Router()
show.get("/", (req: Request, res: Response) => {
Show.findAll()
.then(shows => {
res.status(200).json(shows)
})
})

View File

@@ -1,20 +1,25 @@
import { Category } from '../models/category.model'
import { Order } from '../models/order.model' import { Order } from '../models/order.model'
import { OrderItem } from '../models/orderItem.model' import { OrderItem } from '../models/orderItem.model'
import { Product } from '../models/product.model'
import { Account } from '../models/account.model' import { Account } from '../models/account.model'
import { Address } from '../models/address.model' import { Address } from '../models/address.model'
import { Payment } from '../models/payment.model' import { Payment } from '../models/payment.model'
import { AccountRole } from '../models/accountRole.model' import { AccountRole } from '../models/accountRole.model'
import { Brand } from '../models/brand.model' import { Rating } from '../models/rating.model'
import { Member } from '../models/member.model'
import { Genre } from '../models/genre.model'
import { Band } from '../models/band.model'
import { Location } from '../models/location.model'
import { Show } from '../models/show.model'
import categories from "./../data/categories.json"
import products from "./../data/products.json"
import accounts from "./../data/accounts.json" import accounts from "./../data/accounts.json"
import orders from "./../data/orders.json" import orders from "./../data/orders.json"
import orderItems from "./../data/orderItems.json" import orderItems from "./../data/orderItems.json"
import accountRoles from "./../data/accountRoles.json" import accountRoles from "./../data/accountRoles.json"
import brands from "./../data/brands.json" import bands from "./../data/bands.json"
import genres from "./../data/genres.json"
import locations from "./../data/locations.json"
import shows from "./../data/shows.json"
/** /**
* Delete all datasets in every database table * Delete all datasets in every database table
@@ -23,9 +28,12 @@ export function deleteAllTables() {
OrderItem.destroy({truncate: true }) OrderItem.destroy({truncate: true })
Order.destroy({ truncate: true }) Order.destroy({ truncate: true })
Product.destroy({ truncate: true }) Rating.destroy({ truncate: true })
Brand.destroy({ truncate: true }) Member.destroy({ truncate: true })
Category.destroy({ truncate: true }) Genre.destroy({ truncate: true })
Band.destroy({ truncate: true })
Location.destroy({ truncate: true })
Show.destroy({ truncate: true })
Address.destroy({ truncate: true }) Address.destroy({ truncate: true })
Payment.destroy({ truncate: true }) Payment.destroy({ truncate: true })
@@ -38,6 +46,8 @@ export function deleteAllTables() {
*/ */
export async function prepopulateDatabase() { export async function prepopulateDatabase() {
AccountRole.bulkCreate(accountRoles.data) AccountRole.bulkCreate(accountRoles.data)
Genre.bulkCreate(genres.data)
Location.bulkCreate(locations.data)
// Account & Sub tables // Account & Sub tables
for (let account of accounts.data) { for (let account of accounts.data) {
@@ -48,10 +58,17 @@ export async function prepopulateDatabase() {
}) })
} }
Category.bulkCreate(categories.data)
Brand.bulkCreate(brands.data)
Product.bulkCreate(products.data)
for(let band of bands.data) {
await Band.create(band)
.then(dataset => {
Rating.bulkCreate(band.ratings)
Member.bulkCreate(band.members)
})
}
Show.bulkCreate(shows.data)
Order.bulkCreate(orders.data) Order.bulkCreate(orders.data)
OrderItem.bulkCreate(orderItems.data) OrderItem.bulkCreate(orderItems.data)
} }

View File

@@ -3,11 +3,12 @@ import cors from 'cors'
import bodyParser from 'body-parser' import bodyParser from 'body-parser'
import { api } from './routes/api.routes' import { api } from './routes/api.routes'
import { startDatabase } from './database' import { startDatabase } from './database'
import { category } from './routes/category.routes'
import { product } from './routes/product.routes'
import { order } from './routes/order.routes' import { order } from './routes/order.routes'
import { account } from './routes/account.routes' import { account } from './routes/account.routes'
import { brand } from './routes/brand.routes' import { show } from './routes/show.routes'
import { band } from './routes/band.routes'
import { genre } from './routes/genre.routes'
import { location } from './routes/location.routes'
const app = express() const app = express()
const port = 3000 const port = 3000
@@ -32,11 +33,12 @@ app.use((req, res, next) => {
// Routes // Routes
app.use("/api", api) app.use("/api", api)
app.use("/categories", category) app.use("/shows", show)
app.use("/products", product) app.use("/bands", band)
app.use("/genres", genre)
app.use("/locations", location)
app.use("/orders", order) app.use("/orders", order)
app.use("/accounts", account) app.use("/accounts", account)
app.use("/brands", brand)
// Start server // Start server