Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Product Migration Guide - NestJS #4

Open
sasasamaes opened this issue Dec 12, 2024 · 17 comments
Open

Product Migration Guide - NestJS #4

sasasamaes opened this issue Dec 12, 2024 · 17 comments
Assignees
Labels
good first issue Good for newcomers ODHack11 Only Dust Hack 11

Comments

@sasasamaes
Copy link
Contributor

sasasamaes commented Dec 12, 2024

Overview

Migration implementation for products table in Revolutionary Farmers platform using NestJS and TypeORM.

Database Structure

Products Table Schema

export class CreateProductTable1624536978524 implements MigrationInterface {
  name = 'CreateProductTable1624536978524';

  public async up(queryRunner: QueryRunner): Promise<void> {
    await queryRunner.createTable(
      new Table({
        name: 'products',
        columns: [
          {
            name: 'id',
            type: 'uuid',
            isPrimary: true,
            generationStrategy: 'uuid',
            default: 'uuid_generate_v4()',
          },
          {
            name: 'name',
            type: 'varchar',
            length: '255',
            isNullable: false,
          },
          {
            name: 'description',
            type: 'text',
            isNullable: true,
          },
          {
            name: 'price',
            type: 'decimal',
            precision: 10,
            scale: 2,
            isNullable: false,
          },
          {
            name: 'price_unit',
            type: 'varchar',
            length: '50',
            isNullable: false,
          },
          {
            name: 'farmer_id',
            type: 'uuid',
            isNullable: false,
          },
          {
            name: 'category',
            type: 'varchar',
            length: '100',
            isNullable: false,
          },
          {
            name: 'sub_category',
            type: 'varchar',
            length: '100',
            isNullable: true,
          },
          {
            name: 'images',
            type: 'jsonb',
            isNullable: true,
          },
          {
            name: 'stock_quantity',
            type: 'integer',
            isNullable: false,
            default: 0,
          },
          {
            name: 'harvest_date',
            type: 'timestamp',
            isNullable: true,
          },
          {
            name: 'certifications',
            type: 'jsonb',
            isNullable: true,
          },
          {
            name: 'seasonality',
            type: 'jsonb',
            isNullable: true,
          },
          {
            name: 'farming_method',
            type: 'varchar',
            length: '50',
            isNullable: true,
          },
          {
            name: 'available_for_delivery',
            type: 'boolean',
            default: false,
          },
          {
            name: 'pickup_available',
            type: 'boolean',
            default: true,
          },
          {
            name: 'created_at',
            type: 'timestamp',
            default: 'CURRENT_TIMESTAMP',
          },
          {
            name: 'updated_at',
            type: 'timestamp',
            default: 'CURRENT_TIMESTAMP',
          },
          {
            name: 'deleted_at',
            type: 'timestamp',
            isNullable: true,
          },
        ],
      }),
      true
    );

    // Add indexes
    await queryRunner.createIndex(
      'products',
      new TableIndex({
        name: 'IDX_PRODUCTS_CATEGORY',
        columnNames: ['category'],
      })
    );

    await queryRunner.createIndex(
      'products',
      new TableIndex({
        name: 'IDX_PRODUCTS_FARMER',
        columnNames: ['farmer_id'],
      })
    );

    // Add foreign key
    await queryRunner.createForeignKey(
      'products',
      new TableForeignKey({
        name: 'FK_PRODUCTS_FARMER',
        columnNames: ['farmer_id'],
        referencedTableName: 'farmers',
        referencedColumnNames: ['id'],
        onDelete: 'CASCADE',
      })
    );
  }

  public async down(queryRunner: QueryRunner): Promise<void> {
    // Remove foreign key
    await queryRunner.dropForeignKey('products', 'FK_PRODUCTS_FARMER');

    // Remove indexes
    await queryRunner.dropIndex('products', 'IDX_PRODUCTS_FARMER');
    await queryRunner.dropIndex('products', 'IDX_PRODUCTS_CATEGORY');

    // Drop table
    await queryRunner.dropTable('products');
  }
}

Implementation Steps

  1. Generate Migration
npm run typeorm:generate-migration -- -n CreateProductTable
  1. Verify Migration
  • Check generated migration file in src/migrations
  • Review schema definitions
  • Validate indexes and foreign keys
  1. Run Migration
npm run typeorm:run-migrations
  1. Verify Database
  • Check table structure
  • Verify indexes
  • Test foreign key constraints

Entity Definition

// src/products/entities/product.entity.ts

import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, CreateDateColumn, UpdateDateColumn, DeleteDateColumn } from 'typeorm';
import { Farmer } from '../../farmers/entities/farmer.entity';

@Entity('products')
export class Product {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column({ length: 255 })
  name: string;

  @Column({ type: 'text', nullable: true })
  description: string;

  @Column({ type: 'decimal', precision: 10, scale: 2 })
  price: number;

  @Column({ name: 'price_unit', length: 50 })
  priceUnit: string;

  @Column({ name: 'farmer_id' })
  farmerId: string;

  @ManyToOne(() => Farmer, farmer => farmer.products)
  farmer: Farmer;

  @Column({ length: 100 })
  category: string;

  @Column({ name: 'sub_category', length: 100, nullable: true })
  subCategory: string;

  @Column({ type: 'jsonb', nullable: true })
  images: string[];

  @Column({ name: 'stock_quantity', default: 0 })
  stockQuantity: number;

  @Column({ name: 'harvest_date', type: 'timestamp', nullable: true })
  harvestDate: Date;

  @Column({ type: 'jsonb', nullable: true })
  certifications: string[];

  @Column({ type: 'jsonb', nullable: true })
  seasonality: string[];

  @Column({ name: 'farming_method', length: 50, nullable: true })
  farmingMethod: string;

  @Column({ name: 'available_for_delivery', default: false })
  availableForDelivery: boolean;

  @Column({ name: 'pickup_available', default: true })
  pickupAvailable: boolean;

  @CreateDateColumn({ name: 'created_at' })
  createdAt: Date;

  @UpdateDateColumn({ name: 'updated_at' })
  updatedAt: Date;

  @DeleteDateColumn({ name: 'deleted_at' })
  deletedAt: Date;
}

Important Notes

Database Considerations

  • Uses UUID for primary keys
  • Implements soft delete pattern
  • Includes audit timestamps
  • Uses JSONB for array storage
  • Implements proper indexing strategy

Validation Rules

  • Name: Required, max 255 chars
  • Price: Required, precision 10, scale 2
  • Category: Required, max 100 chars
  • FarmerId: Required, valid UUID
  • StockQuantity: Required, non-negative

Testing

# Revert migration
npm run typeorm:revert-migration

# Re-run migration
npm run typeorm:run-migrations

Error Handling

  • Migration includes proper up/down methods
  • Foreign key constraint ensures data integrity
  • Indexes optimize common queries
  • Soft delete prevents data loss
@ManuelJG1999 ManuelJG1999 added good first issue Good for newcomers ODHack11 Only Dust Hack 11 labels Dec 12, 2024
@salazarsebas salazarsebas transferred this issue from another repository Dec 12, 2024
@josephchimebuka
Copy link

Could I grab this task?

@mimisavage
Copy link

Let me handle this issue!

@khayss
Copy link

khayss commented Dec 12, 2024

Mind if I try this one?

I have experience in building backend servers with NestJs. I'm familiar with what is required to complete this issue.

I can make the shell environment for executing NestJs backend command.

@derianrddev
Copy link

Hello Revolutionary Farmers Team,

I am Derian Rodríguez, a member of the Dojo Coding community ⛩️💻. I’m excited to contribute to your Stellar-based project during the Only Dust Hackathon #11 🚀.

As a full-stack developer, I have experience in:

Frontend: JavaScript/TypeScript, TailwindCSS, React, Next.js, and shadcn/ui.
Backend: Node.js (Express.js, Nest.js).
Web3: Cairo.
Plan to Address the Issue
Run the necessary Nest.js commands to initialize the backend's base structure.
Configure the project's initial structure, including folders for modules, controllers, and services.
Implement basic configurations such as database connection, environment variables, and essential middleware.
Consult with project maintainers if there are specific questions about requirements or customization.
Here are my profiles:

GitHub
OnlyDust
Thank you for considering my application.

@abdegenius
Copy link

Can I start working on this?

@Supa-mega
Copy link

Can I try solving this issue?

@chigozzdevv
Copy link

I'd like to take this issue.

1 similar comment
@caxtonacollins
Copy link

I'd like to take this issue.

@Akshola00
Copy link

Can I try solving this issue?

@kayceeDev
Copy link

Can I contribute to this one?

@coxmars
Copy link

coxmars commented Dec 12, 2024

I'm a software developer with 2+ years of experience and I have worked with backend technologies such as Cairo, Java, C# and frontend with React, NextJS, JS/TS. Also, I'm a member of the Dojo Coding community here in CR and I have made contributions in Cairo VM Go, Cairo VM TS, Cairo Lints etc. Likewise, I’m a Cairo developer working in ByteBuildersLabs creating on-chain games using the Dojo framework.

This is my approach:

  • I will set up a basic Nest.js project shell using the recommended Nest.js CLI commands to scaffold the backend structure.
  • I’ll configure the necessary modules, controllers or services based on the project requirements.
  • I’ll ensure the project includes essential configurations such as environment management, logging, and dependency injection setup.
  • If needed, I will consult with the maintainers for specific project details or additional requirements.
  • Finally, I’ll test the shell setup to ensure it is ready for further development and integration.

ET: 2 days

@gregemax
Copy link

Is it okay if I tackle this?
modular backends using NestJS. I’d like to tackle this issue and set up the initial backend structure.

NestJS Setup: Use NestJS CLI to initialize the project structure.
Configuration: Configure essential modules, such as TypeORM for database integration, JWT for authentication, and necessary middlewares.
Project Shell: Set up the foundational shell with appropriate file structure for scalability.

I’ve reviewed the Contributor’s Guide and am excited to contribute. Is it okay if I tackle this?
i have work with nestjs u can check my github for proof

@ShantelPeters
Copy link

Could I grab this task?

@Jagadeeshftw
Copy link

Hi, I’d love to work on this issue as I have strong experience with both Stellar and Rust. I’ve developed secure and efficient smart contracts, blockchain integrations, and high-performance backend systems. Please assign this to me, and I’ll ensure to deliver a robust and high-quality PR within 12-24 hours.

@Benjtalkshow
Copy link

I am a Full Stack Developer with a strong background in blockchain and extensive experience in Next.js/React, TypeScript, and Rust. I’ve made over 49 contributions to over 17 projects in the OnlyDust ecosystem, solving complex issues and delivering efficient, scalable solutions.

I can handle this task.
ETA is 3days.

@sasasamaes sasasamaes changed the title Backend initial structure Product Migration Guide - NestJS Dec 17, 2024
@sasasamaes
Copy link
Contributor Author

Hello @coxmars have you been able to work on this issue?

@Jagadeeshftw
Copy link

@sasasamaes can this be assigned to me? I have good knowledge in nest js.

@sasasamaes sasasamaes assigned sasasamaes and unassigned coxmars Dec 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue Good for newcomers ODHack11 Only Dust Hack 11
Projects
None yet
Development

No branches or pull requests