# Milestone 3
Updates from Team We Die in CS Since Milestone 2:
Joshua Petitma (Users Guru):
- Reworked backend to make storing and querying data easier
- Allow users to view and update their profile
Amy Wang (Carts Guru):
Ellie Kim (Social Guru):
- Added page for each user that allows all of their reviews to be accessed from their ID
- Each review contains relevant info for the product and the buyer's impression
Haoning Jiang (Products Guru):
- Implemented more complex ways to search for products, as well as a detailed product page with relevant info for each product.
Gene Yang (Sellers Guru):
- Implemented all basic features and now any registered seller is able to manage all of the various items in their inventory and also add new items.
- Sellers can also track and change the status of any orders they have received for their products.
# Generating Mock Data
generateMockData.ts can be found in /mocks/generateMockData.ts
# GitLab Repo
[Link to Repo](https://gitlab.oit.duke.edu/gy36/mini-amazon)
# Figma Design
[Link to Figma](https://www.figma.com/file/UYAvwwddvX5H6G0jC3xbLz/unfriendly-amazon?node-id=0%3A1&t=FgWjnLgNNaqk56TV-0)
# SCHEMA STUFF
[instructions](https://docs.google.com/document/d/1dYfsWaI_Wdm0unN2Us2pQvCNKx4f9gL0YLf2vxSeyb0/edit#)
## Users
```ts
import { IProductSummary } from "@lib/product/product_models";
import { IProductReview } from "@lib/review/review_models";
import { Schema } from "mongoose";
import { createMongooseModel, createRedactedMongooseModel, DB, ObjectId } from "../util";
export interface UserToken {
user_uuid: string;
seller?: boolean;
}
export interface IUserAccountData {
uuid: string;
user_name: string;
email: string;
password: string;
seller?: boolean;
profile_image_url: string;
seller_data?: SellerData;
account_balance: number;
credit_cards: ICreditCard[];
address: string;
}
export type ICreditCard = {
name: string;
billing_address: string;
number: string;
cvv: string;
expiration: string;
};
const creditCardSchema = new Schema<ICreditCard>({
billing_address: String,
cvv: Number,
expiration: String,
name: String,
number: String,
});
const userAccountDataSchema = new Schema<IUserAccountData>({
uuid: { type: String, required: true, unique: true },
user_name: { type: String, required: true, unique: false },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
address: { type: String, required: false },
seller: { type: Boolean, required: false, default: 0 },
profile_image_url: {
type: String,
required: false,
default:
"https://www.pngitem.com/pimgs/m/581-5813504_avatar-dummy-png-transparent-png.png",
},
account_balance: { type: Number, required: true, default: 0 },
credit_cards: [creditCardSchema],
});
export const UserAccountData = createMongooseModel(
"UserAccountData",
userAccountDataSchema
);
export const UserPublicData = createRedactedMongooseModel({
keep: ["user_name", "profile_image_url", "uuid"],
newSchemaName: "UserPublicData",
originalModel: UserAccountData,
});
export type IUserPublicData = DB<typeof UserPublicData>
type SellerData = {
email: string;
instagram: string;
address: string;
topReviews: IProductReview[];
seller_average_rating: number;
};
// Just for the hw, will delete below line later
export interface IUserPurchase {
user_uuid: string;
product_qty: number;
product: IProductSummary
}
const userPurchaseSchema = new Schema<IUserPurchase>({
user_uuid: { type: String },
product: { type: ObjectId, ref: 'ProductSummary' }
});
export const UserPurchase = createMongooseModel(
"UserPurchase",
userPurchaseSchema
);
```
## Sellers
``` ts
interface ISellerInventory {
products: IProductInventoryLog[];
seller_id: string;
}
interface ISellerOrderHistory {
orders: ISellerOrder[];
}
type ISellerOrder = {
uuid: string;
seller_id: string;
order_date: string;
delivery_date: string;
number_items: number;
products: IPurchasedProduct[];
status: "Arrived" | "Shipped" | "Pending";
total_cost: number;
user: string;
}
type IPurchasedProduct = {
product: IDetailedProductPage
quantity: number
}
type IProductInventoryLog = {
stock: number;
seller_id: string;
product: IDetailedProductPage;
}
```
## Products
``` ts
interface IProductSearchResult {
search_results: IProductSummary[];
}
interface IDetailedProductPage {
uuid: string;
name: string;
description: string;
image_url: string;
price: number;
avg_rating: number;
seller: IUserPublicData;
category: string;
//quantity: number;
}
```
## Carts
``` ts
```
## Social
```ts
export type IReview = {
user: IUserPublicData;
num_stars: number;
review_text: string;
purchase_date: string;
review_date: string;
uuid: string;
}
export type IProductReview = {
product: IProductSummary;
} & IReview
export type ISellerReview = {
seller_id: string;
} & IReview
// Each user should be able to list all their ratings/reviews
// sorted in reverse chronological order by default
export interface IUserReviewHistory {
product_reviews: IProductReview[]
seller_reviews: ISellerReview[]
}
interface RatingHistory {
avg_num_stars: number;
total_num_ratings: number;
}
export interface IProductRatingHistory extends RatingHistory {
product_reviews: IProductReview[]
}
export interface ISellerRatingHistory extends RatingHistory {
seller_reviews: ISellerReview[]
}
const reviewSchema = new Schema<IReview>({
user: { type: ObjectId, ref: "UserPublicData", autopopulate: true},
num_stars: { type: Number, required: true, unique: false },
review_text: { type: String, required: true, unique: false },
purchase_date: { type: String, required: true, unique: false },
review_date: { type: String, required: true, unique: false },
uuid: { type: String, required: true, unique: true },
});
const productReviewSchema = new Schema<IProductReview>({
...reviewSchema.obj, product:
{ type: ObjectId, ref: "ProductSummary", autopopulate: true },
});
const sellerReviewSchema = new Schema<ISellerReview>({
...reviewSchema.obj, seller_id: { type: String, required: true, unique: true }
});
export const ProductReview = createMongooseModel(
"ProductReview",
productReviewSchema
);
export const SellerReview = createMongooseModel(
"SellerReview",
sellerReviewSchema
);
```