Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0d5d22e
Fixing database entity inconsistencies based on notes
Juwang110 Oct 26, 2025
2825d0d
making item_id not nullable in allocations
Juwang110 Oct 29, 2025
be5d6d0
refactoring to use donation relation instead of id
Juwang110 Nov 7, 2025
fcfc780
db pantry table/entity updates
swarkewalia Nov 10, 2025
16d8645
updated usages in code
swarkewalia Nov 10, 2025
8ab120a
todo item
swarkewalia Nov 11, 2025
21d4939
typeorm file changes
swarkewalia Nov 11, 2025
04e7d80
Merge branch 'main' into sk/SSF-82-pantry-user-refactoring
swarkewalia Nov 18, 2025
b9cf998
Merge branch 'main' into jw/SSF-80-database-backend-inconsistencies
amywng Nov 18, 2025
70e7463
Merge branch - resolve conflicts
swarkewalia Nov 19, 2025
7e573f9
Merge branch 'sk/SSF-82-pantry-user-refactoring' of https://github.co…
swarkewalia Nov 19, 2025
c8b7690
Merge branch 'main' into sk/SSF-82-pantry-user-refactoring
swarkewalia Nov 19, 2025
da318a9
merge changes
swarkewalia Nov 19, 2025
42fd976
Remove extra files
swarkewalia Nov 19, 2025
697ce83
gitignore cache files
swarkewalia Nov 19, 2025
1cc8987
Review fixes
swarkewalia Nov 19, 2025
99a4e98
adding validate Id call for donation items route
Juwang110 Nov 19, 2025
0a65da8
Merge pull request #60 from Code-4-Community/jw/SSF-80-database-backe…
Juwang110 Nov 19, 2025
5725348
merge main in branch and fix dependency files
swarkewalia Nov 20, 2025
a1e736a
fix gitignore
swarkewalia Nov 20, 2025
829cc0f
fixed extra space
swarkewalia Nov 22, 2025
0d607b7
add constraint
swarkewalia Nov 22, 2025
0855f8f
Fixed ssf rep id
dburkhart07 Nov 23, 2025
8d2162a
Merge pull request #65 from Code-4-Community/sk/SSF-82-pantry-user-re…
dburkhart07 Nov 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/backend/src/allocations/allocations.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class Allocation {
@Column({ name: 'order_id', type: 'int' })
orderId: number;

@Column({ name: 'item_id', type: 'int' })
@Column({ name: 'item_id', type: 'int', nullable: false })
itemId: number;

@ManyToOne(() => DonationItem, (item) => item.allocations)
Expand Down
4 changes: 4 additions & 0 deletions apps/backend/src/config/typeorm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { UpdateRequestTable1741571847063 } from '../migrations/1741571847063-upd
import { RemoveOrderIdFromRequests1744133526650 } from '../migrations/1744133526650-removeOrderIdFromRequests';
import { AddOrders1739496585940 } from '../migrations/1739496585940-addOrders';
import { UpdatePantriesTable1742739750279 } from '../migrations/1742739750279-updatePantriesTable';
import { UpdatePantryUserFields1731171000000 } from '../migrations/1731171000000-UpdatePantryUserFields';
import { RemoveOrdersDonationId1761500262238 } from '../migrations/1761500262238-RemoveOrdersDonationId';

const config = {
type: 'postgres',
Expand Down Expand Up @@ -47,6 +49,8 @@ const config = {
UpdateFoodRequests1744051370129,
RemoveOrderIdFromRequests1744133526650,
UpdatePantriesTable1742739750279,
UpdatePantryUserFields1731171000000,
RemoveOrdersDonationId1761500262238,
],
};

Expand Down
3 changes: 0 additions & 3 deletions apps/backend/src/donationItems/donationItems.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,6 @@ export class DonationItem {
@PrimaryGeneratedColumn({ name: 'item_id' })
itemId: number;

@Column({ name: 'donation_id', type: 'int' })
donationId: number;

@ManyToOne(() => Donation, { nullable: false })
@JoinColumn({ name: 'donation_id', referencedColumnName: 'donationId' })
donation: Donation;
Expand Down
3 changes: 2 additions & 1 deletion apps/backend/src/donationItems/donationItems.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { DonationItem } from './donationItems.entity';
import { JwtStrategy } from '../auth/jwt.strategy';
import { AuthService } from '../auth/auth.service';
import { DonationItemsController } from './donationItems.controller';
import { Donation } from '../donations/donations.entity';

@Module({
imports: [TypeOrmModule.forFeature([DonationItem])],
imports: [TypeOrmModule.forFeature([DonationItem, Donation])],
controllers: [DonationItemsController],
providers: [DonationItemsService, AuthService, JwtStrategy],
})
Expand Down
10 changes: 8 additions & 2 deletions apps/backend/src/donationItems/donationItems.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DonationItem } from './donationItems.entity';
import { validateId } from '../utils/validation.utils';
import { Donation } from '../donations/donations.entity';

@Injectable()
export class DonationItemsService {
constructor(
@InjectRepository(DonationItem) private repo: Repository<DonationItem>,
@InjectRepository(Donation) private donationRepo: Repository<Donation>,
) {}

async getAllDonationItems(donationId: number): Promise<DonationItem[]> {
validateId(donationId, 'Donation');
return this.repo.findBy({ donationId });
return this.repo.find({ where: { donation: { donationId } } });
}

async create(
Expand All @@ -25,8 +27,12 @@ export class DonationItemsService {
estimatedValue: number,
foodType: string,
) {
validateId(donationId, 'Donation');
const donation = await this.donationRepo.findOneBy({ donationId });
if (!donation) throw new NotFoundException('Donation not found');

const donationItem = this.repo.create({
donationId,
donation,
itemName,
quantity,
reservedQuantity,
Expand Down
4 changes: 2 additions & 2 deletions apps/backend/src/foodRequests/request.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
Column,
PrimaryGeneratedColumn,
CreateDateColumn,
OneToOne,
OneToMany,
} from 'typeorm';
import { Order } from '../orders/order.entity';

Expand Down Expand Up @@ -40,6 +40,6 @@ export class FoodRequest {
@Column({ name: 'photos', type: 'text', array: true, nullable: true })
photos: string[];

@OneToOne(() => Order, (order) => order.request, { nullable: true })
@OneToMany(() => Order, (order) => order.request, { nullable: true })
order: Order;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class UpdatePantryUserFields1731171000000 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE pantries DROP COLUMN IF EXISTS ssf_representative_id;
ALTER TABLE pantries RENAME COLUMN pantry_representative_id TO pantry_user_id;`,
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE pantries RENAME COLUMN pantry_user_id TO pantry_representative_id;
ALTER TABLE pantries ADD COLUMN ssf_representative_id INT;
ALTER TABLE pantries ADD CONSTRAINT fk_ssf_representative_id
FOREIGN KEY (ssf_representative_id) REFERENCES users(user_id);`,
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { MigrationInterface, QueryRunner } from 'typeorm';

export class RemoveOrdersDonationId1761500262238 implements MigrationInterface {
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE orders
DROP COLUMN donation_id
`);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`
ALTER TABLE orders
ADD COLUMN donation_id INT NOT NULL
`);
}
}
8 changes: 0 additions & 8 deletions apps/backend/src/orders/order.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Order } from './order.entity';
import { Pantry } from '../pantries/pantries.entity';
import { FoodManufacturer } from '../foodManufacturers/manufacturer.entity';
import { FoodRequest } from '../foodRequests/request.entity';
import { Donation } from '../donations/donations.entity';
import { AllocationsService } from '../allocations/allocations.service';

@Controller('orders')
Expand Down Expand Up @@ -66,13 +65,6 @@ export class OrdersController {
return this.ordersService.findOrderFoodManufacturer(orderId);
}

@Get(':orderId/donation')
async getDonationFromOrder(
@Param('orderId', ParseIntPipe) orderId: number,
): Promise<Donation> {
return this.ordersService.findOrderDonation(orderId);
}

@Get('/:orderId')
async getOrder(
@Param('orderId', ParseIntPipe) orderId: number,
Expand Down
12 changes: 2 additions & 10 deletions apps/backend/src/orders/order.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
CreateDateColumn,
ManyToOne,
JoinColumn,
OneToOne,

Check warning on line 8 in apps/backend/src/orders/order.entity.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

'OneToOne' is defined but never used
} from 'typeorm';
import { FoodRequest } from '../foodRequests/request.entity';
import { Pantry } from '../pantries/pantries.entity';
import { FoodManufacturer } from '../foodManufacturers/manufacturer.entity';
import { Donation } from '../donations/donations.entity';

@Entity('orders')
export class Order {
Expand All @@ -24,7 +23,7 @@
})
pantry: Pantry;

@OneToOne(() => FoodRequest, { nullable: false })
@ManyToOne(() => FoodRequest, { nullable: false })
@JoinColumn({
name: 'request_id',
referencedColumnName: 'requestId',
Expand All @@ -34,7 +33,7 @@
@Column({ name: 'request_id' })
requestId: number;

@ManyToOne(() => FoodManufacturer, { nullable: true })
@ManyToOne(() => FoodManufacturer, { nullable: false })
@JoinColumn({
name: 'shipped_by',
referencedColumnName: 'foodManufacturerId',
Expand All @@ -44,13 +43,6 @@
@Column({ name: 'shipped_by', nullable: true })
shippedBy: number;

@ManyToOne(() => Donation, { nullable: false })
@JoinColumn({
name: 'donation_id',
referencedColumnName: 'donationId',
})
donation: Donation;

@Column({ name: 'status', type: 'varchar', length: 25, default: 'pending' })
status: string;

Expand Down
2 changes: 1 addition & 1 deletion apps/backend/src/orders/order.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const mockPantry: Pantry = {
serveAllergicChildren: '',
newsletterSubscription: false,
restrictions: [],
pantryRepresentative: null as unknown as User,
pantryUser: null as unknown as User,
status: 'active',
dateApplied: new Date(),
activities: [],
Expand Down
14 changes: 0 additions & 14 deletions apps/backend/src/orders/order.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { Pantry } from '../pantries/pantries.entity';
import { FoodManufacturer } from '../foodManufacturers/manufacturer.entity';
import { FoodRequest } from '../foodRequests/request.entity';
import { Donation } from '../donations/donations.entity';

Check warning on line 8 in apps/backend/src/orders/order.service.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

'Donation' is defined but never used
import { validateId } from '../utils/validation.utils';

@Injectable()
Expand Down Expand Up @@ -116,20 +116,6 @@
return order.foodManufacturer;
}

async findOrderDonation(orderId: number): Promise<Donation> {
validateId(orderId, 'Order');

const order = await this.repo.findOne({
where: { orderId },
relations: ['donation'],
});

if (!order) {
throw new NotFoundException(`Order ${orderId} not found`);
}
return order.donation;
}

async updateStatus(orderId: number, newStatus: string) {
validateId(orderId, 'Order');

Expand Down
8 changes: 0 additions & 8 deletions apps/backend/src/pantries/pantries.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
} from '@nestjs/common';
import { Pantry } from './pantries.entity';
import { PantriesService } from './pantries.service';
import { User } from '../users/user.entity';
import { PantryApplicationDto } from './dtos/pantry-application.dto';
import { ApiBody } from '@nestjs/swagger';

Expand All @@ -21,13 +20,6 @@ export class PantriesController {
return this.pantriesService.getPendingPantries();
}

@Get('/:pantryId/ssf-contact')
async getSSFRep(
@Param('pantryId', ParseIntPipe) pantryId: number,
): Promise<User> {
return this.pantriesService.findSSFRep(pantryId);
}

@Get('/:pantryId')
async getPantry(
@Param('pantryId', ParseIntPipe) pantryId: number,
Expand Down
16 changes: 4 additions & 12 deletions apps/backend/src/pantries/pantries.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {
PrimaryGeneratedColumn,
OneToOne,
JoinColumn,
ManyToOne,
} from 'typeorm';
import { User } from '../users/user.entity';

Expand Down Expand Up @@ -89,22 +88,15 @@ export class Pantry {
@Column({ name: 'restrictions', type: 'text', array: true })
restrictions: string[];

@ManyToOne(() => User, { nullable: true })
@JoinColumn({
name: 'ssf_representative_id',
referencedColumnName: 'id',
})
ssfRepresentative?: User;

// cascade: ['insert'] means that when we create a new
// pantry, the representative will automatically be added
// pantry, the pantry user will automatically be added
// to the User table
@OneToOne(() => User, { nullable: false, cascade: ['insert'] })
@OneToOne(() => User, { nullable: false, cascade: ['insert'], onDelete: 'CASCADE' })
@JoinColumn({
name: 'pantry_representative_id',
name: 'pantry_user_id',
referencedColumnName: 'id',
})
pantryRepresentative: User;
pantryUser: User;

@Column({ name: 'status', type: 'varchar', length: 50, default: 'pending' })
status: string;
Expand Down
22 changes: 5 additions & 17 deletions apps/backend/src/pantries/pantries.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ export class PantriesService {
}

async getPendingPantries(): Promise<Pantry[]> {
return await this.repo.find({ where: { status: 'pending' } });
return await this.repo.find({
where: { status: 'pending' },
relations: ['pantryUser'],
});
}

async addPantry(pantryData: PantryApplicationDto) {
Expand All @@ -36,7 +39,7 @@ export class PantriesService {
pantryContact.email = pantryData.contactEmail;
pantryContact.phone = pantryData.contactPhone;

pantry.pantryRepresentative = pantryContact;
pantry.pantryUser = pantryContact;

pantry.pantryName = pantryData.pantryName;
pantry.addressLine1 = pantryData.addressLine1;
Expand Down Expand Up @@ -86,19 +89,4 @@ export class PantriesService {

await this.repo.update(id, { status: 'denied' });
}

async findSSFRep(pantryId: number): Promise<User> {
validateId(pantryId, 'Pantry');

const pantry = await this.repo.findOne({
where: { pantryId },
relations: ['ssfRepresentative'],
});

if (!pantry) {
throw new NotFoundException(`Pantry ${pantryId} not found`);
}

return pantry.ssfRepresentative;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
OneToOne,
JoinColumn,
ManyToOne,
Column,

Check warning on line 7 in apps/backend/src/volunteerAssignments/volunteerAssignments.entity.ts

View workflow job for this annotation

GitHub Actions / pre-deploy

'Column' is defined but never used
} from 'typeorm';
import { User } from '../users/user.entity';
import { Pantry } from '../pantries/pantries.entity';
Expand All @@ -14,9 +14,6 @@
@PrimaryGeneratedColumn({ name: 'assignment_id' })
assignmentId: number;

@Column({ name: 'volunteer_id' })
volunteerId: number;

@ManyToOne(() => User, { nullable: false })
@JoinColumn({
name: 'volunteer_id',
Expand Down
6 changes: 0 additions & 6 deletions apps/frontend/src/api/apiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,6 @@ export class ApiClient {
return this.get(`/api/requests/${requestId}`) as Promise<FoodRequest>;
}

public async getDonationFromOrder(orderId: number): Promise<Donation | null> {
return this.axiosInstance
.get(`/api/orders/${orderId}/donation`)
.then((response) => response.data);
}

public async getOrderDonation(donationId: number): Promise<Donation> {
return this.get(`/api/donations/${donationId}`) as Promise<Donation>;
}
Expand Down
Loading
Loading