---
# System prepended metadata

title: Milestone 3

---

# 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
);


```







