refactor: rename marketplace to storefront across the entire monorepo
Build & Deploy / Build & Push Docker Image (push) Successful in 1m2s
Test / Type Check (all packages) (push) Failing after 28s
Test / API Unit Tests (push) Has been skipped
Test / Homepage Unit Tests (push) Has been skipped
Test / Storefront Unit Tests (push) Has been skipped
Test / Admin Unit Tests (push) Has been skipped
Test / Dashboard Unit Tests (push) Has been skipped
Test / API Integration Tests (push) Has been skipped
Build & Deploy / Deploy to VPS (push) Successful in 3s

Comprehensive rename of all marketplace references to storefront:
- API module: apps/api/src/modules/marketplace/ → storefront/
- Components: MarketplaceHeader → StorefrontHeader, MarketplaceShell →
  StorefrontShell, MarketplaceFooter → StorefrontFooter
- Types: marketplace-homepage.ts → storefront-homepage.ts
- Test files: employee-marketplace-* → employee-storefront-*
- All source code identifiers, imports, route paths, and strings
- Documentation (docs/), CI config (.gitlab-ci.yml), scripts
- Dashboard, admin, storefront workspace references
- Prisma field names preserved (isListedOnMarketplace, marketplaceRating,
  marketplaceFunnelEvent) as they map to database schema

Validation:
- API type-check: 0 errors
- Storefront type-check: 0 errors
- Dashboard type-check: 0 errors
- Full monorepo type-check: only pre-existing admin TS18046
This commit is contained in:
root
2026-06-28 01:14:46 -04:00
parent bffda95a7c
commit 8aab968e09
147 changed files with 829 additions and 829 deletions
@@ -40,12 +40,12 @@ vi.mock('../../modules/notifications/notification.service', () => ({
getRenterPreferences: vi.fn(),
setRenterPreferences: vi.fn(),
}))
vi.mock('../../modules/marketplace/marketplace.service', () => ({
vi.mock('../../modules/storefront/storefront.service', () => ({
getCities: vi.fn(),
getListedCompanies: vi.fn(),
searchVehicles: vi.fn(),
getVehicleDetail: vi.fn(),
createMarketplaceReservation: vi.fn(),
createStorefrontReservation: vi.fn(),
getCompanyPage: vi.fn(),
getCompanyReviews: vi.fn(),
getCompanyVehicles: vi.fn(),
@@ -61,11 +61,11 @@ import request from 'supertest'
import { createApp } from '../../app'
import * as employeeService from '../../modules/auth/auth.employee.service'
import * as notificationService from '../../modules/notifications/notification.service'
import * as marketplaceService from '../../modules/marketplace/marketplace.service'
import * as storefrontService from '../../modules/storefront/storefront.service'
const app = createApp()
describe('employee, notification, and marketplace API validation contracts', () => {
describe('employee, notification, and storefront API validation contracts', () => {
beforeEach(() => {
vi.clearAllMocks()
vi.mocked(employeeService.login).mockResolvedValue({ token: 'jwt', employee: { id: 'employee_1' } } as never)
@@ -73,8 +73,8 @@ describe('employee, notification, and marketplace API validation contracts', ()
vi.mocked(employeeService.updateLanguage).mockResolvedValue({ language: 'ar' } as never)
vi.mocked(employeeService.resetPassword).mockResolvedValue({ message: 'Password updated successfully. You can now sign in.' } as never)
vi.mocked(notificationService.setPreferences).mockResolvedValue({ success: true } as never)
vi.mocked(marketplaceService.searchVehicles).mockResolvedValue({ companies: [], vehicles: [], pagination: { page: 1, pageSize: 20, total: 0 } } as never)
vi.mocked(marketplaceService.submitReview).mockResolvedValue({ id: 'review_1' } as never)
vi.mocked(storefrontService.searchVehicles).mockResolvedValue({ companies: [], vehicles: [], pagination: { page: 1, pageSize: 20, total: 0 } } as never)
vi.mocked(storefrontService.submitReview).mockResolvedValue({ id: 'review_1' } as never)
})
it('normalizes employee login email before service execution', async () => {
@@ -110,11 +110,11 @@ describe('employee, notification, and marketplace API validation contracts', ()
expect(notificationService.setPreferences).not.toHaveBeenCalled()
})
it('defaults marketplace search pagination at the public route boundary', async () => {
const res = await request(app).get('/api/v1/marketplace/search?city=Casablanca')
it('defaults storefront search pagination at the public route boundary', async () => {
const res = await request(app).get('/api/v1/storefront/search?city=Casablanca')
expect(res.status).toBe(200)
expect(marketplaceService.searchVehicles).toHaveBeenCalledWith(expect.objectContaining({
expect(storefrontService.searchVehicles).toHaveBeenCalledWith(expect.objectContaining({
city: 'Casablanca',
page: 1,
pageSize: 20,
@@ -122,7 +122,7 @@ describe('employee, notification, and marketplace API validation contracts', ()
})
it('rejects out-of-range public review ratings before service execution', async () => {
const res = await request(app).post('/api/v1/marketplace/review/token_123').send({
const res = await request(app).post('/api/v1/storefront/review/token_123').send({
overallRating: 6,
vehicleRating: 5,
serviceRating: 5,
@@ -130,6 +130,6 @@ describe('employee, notification, and marketplace API validation contracts', ()
})
expect(res.status).toBe(400)
expect(marketplaceService.submitReview).not.toHaveBeenCalled()
expect(storefrontService.submitReview).not.toHaveBeenCalled()
})
})
@@ -30,12 +30,12 @@ vi.mock('../../modules/site/site.service', () => ({
handleContact: vi.fn(),
}))
vi.mock('../../modules/marketplace/marketplace.service', () => ({
vi.mock('../../modules/storefront/storefront.service', () => ({
getPublicOffers: vi.fn(),
getCities: vi.fn(),
getListedCompanies: vi.fn(),
searchVehicles: vi.fn(),
createMarketplaceReservation: vi.fn(),
createStorefrontReservation: vi.fn(),
getReviewContext: vi.fn(),
submitReview: vi.fn(),
validateOfferCode: vi.fn(),
@@ -49,7 +49,7 @@ vi.mock('../../modules/marketplace/marketplace.service', () => ({
import request from 'supertest'
import { createApp } from '../../app'
import * as siteService from '../../modules/site/site.service'
import * as marketplaceService from '../../modules/marketplace/marketplace.service'
import * as storefrontService from '../../modules/storefront/storefront.service'
const app = createApp()
@@ -59,9 +59,9 @@ describe('public validation API contracts', () => {
vi.mocked(siteService.checkAvailability).mockResolvedValue({ available: true, nextAvailableAt: null } as never)
vi.mocked(siteService.initPayment).mockResolvedValue({ checkoutUrl: 'https://pay.example.test' } as never)
vi.mocked(siteService.handleContact).mockResolvedValue({ success: true } as never)
vi.mocked(marketplaceService.searchVehicles).mockResolvedValue({ data: [], pagination: { page: 1, pageSize: 20 } } as never)
vi.mocked(marketplaceService.createMarketplaceReservation).mockResolvedValue({ id: 'reservation_1' } as never)
vi.mocked(marketplaceService.submitReview).mockResolvedValue({ id: 'review_1' } as never)
vi.mocked(storefrontService.searchVehicles).mockResolvedValue({ data: [], pagination: { page: 1, pageSize: 20 } } as never)
vi.mocked(storefrontService.createStorefrontReservation).mockResolvedValue({ id: 'reservation_1' } as never)
vi.mocked(storefrontService.submitReview).mockResolvedValue({ id: 'review_1' } as never)
})
it('rejects malformed public availability checks before site service execution', async () => {
@@ -120,11 +120,11 @@ describe('public validation API contracts', () => {
})
})
it('coerces marketplace search pagination and price filters', async () => {
const res = await request(app).get('/api/v1/marketplace/search?city=Rabat&maxPrice=500&page=2&pageSize=30')
it('coerces storefront search pagination and price filters', async () => {
const res = await request(app).get('/api/v1/storefront/search?city=Rabat&maxPrice=500&page=2&pageSize=30')
expect(res.status).toBe(200)
expect(marketplaceService.searchVehicles).toHaveBeenCalledWith({
expect(storefrontService.searchVehicles).toHaveBeenCalledWith({
city: 'Rabat',
maxPrice: 500,
page: 2,
@@ -132,15 +132,15 @@ describe('public validation API contracts', () => {
})
})
it('rejects oversized marketplace pagination before search execution', async () => {
const res = await request(app).get('/api/v1/marketplace/search?pageSize=500')
it('rejects oversized storefront pagination before search execution', async () => {
const res = await request(app).get('/api/v1/storefront/search?pageSize=500')
expect(res.status).toBe(400)
expect(marketplaceService.searchVehicles).not.toHaveBeenCalled()
expect(storefrontService.searchVehicles).not.toHaveBeenCalled()
})
it('rejects marketplace reservations with invalid public contact data before service execution', async () => {
const res = await request(app).post('/api/v1/marketplace/reservations').send({
it('rejects storefront reservations with invalid public contact data before service execution', async () => {
const res = await request(app).post('/api/v1/storefront/reservations').send({
vehicleId: 'ckvvehicle000000000000001',
companySlug: 'atlas-cars',
firstName: 'Aya',
@@ -151,13 +151,13 @@ describe('public validation API contracts', () => {
})
expect(res.status).toBe(400)
expect(marketplaceService.createMarketplaceReservation).not.toHaveBeenCalled()
expect(storefrontService.createStorefrontReservation).not.toHaveBeenCalled()
})
it('rejects invalid public review ratings before creating reviews', async () => {
const res = await request(app).post('/api/v1/marketplace/review/token_1').send({ overallRating: 6 })
const res = await request(app).post('/api/v1/storefront/review/token_1').send({ overallRating: 6 })
expect(res.status).toBe(400)
expect(marketplaceService.submitReview).not.toHaveBeenCalled()
expect(storefrontService.submitReview).not.toHaveBeenCalled()
})
})
@@ -10,7 +10,7 @@ import { createApp } from '../../app'
const app = createApp()
describe('employee and marketplace public boundary smoke', () => {
describe('employee and storefront public boundary smoke', () => {
it('rejects malformed employee login payloads without leaking internals', async () => {
const res = await request(app).post('/api/v1/auth/employee/login').send({ email: 'not-an-email', password: 'x' })
@@ -19,7 +19,7 @@ describe('employee and marketplace public boundary smoke', () => {
})
it('rejects invalid public review payloads without executing private infrastructure', async () => {
const res = await request(app).post('/api/v1/marketplace/review/token_123').send({ overallRating: 0 })
const res = await request(app).post('/api/v1/storefront/review/token_123').send({ overallRating: 0 })
expect(res.status).toBe(400)
expect(JSON.stringify(res.body)).not.toContain('Prisma')
@@ -24,12 +24,12 @@ vi.mock('../../modules/site/site.service', () => ({
capturePaypal: vi.fn(),
handleContact: vi.fn(),
}))
vi.mock('../../modules/marketplace/marketplace.service', () => ({
vi.mock('../../modules/storefront/storefront.service', () => ({
getPublicOffers: vi.fn(),
getCities: vi.fn(),
getListedCompanies: vi.fn(),
searchVehicles: vi.fn(),
createMarketplaceReservation: vi.fn(),
createStorefrontReservation: vi.fn(),
getReviewContext: vi.fn(),
submitReview: vi.fn(),
validateOfferCode: vi.fn(),
@@ -43,7 +43,7 @@ vi.mock('../../modules/marketplace/marketplace.service', () => ({
import request from 'supertest'
import { createApp } from '../../app'
import * as siteService from '../../modules/site/site.service'
import * as marketplaceService from '../../modules/marketplace/marketplace.service'
import * as storefrontService from '../../modules/storefront/storefront.service'
const app = createApp()
@@ -61,8 +61,8 @@ describe('public validation e2e smoke', () => {
expect(payment.status).toBe(400)
expect(siteService.initPayment).not.toHaveBeenCalled()
const review = await request(app).post('/api/v1/marketplace/review/token_1').send({ overallRating: 0 })
const review = await request(app).post('/api/v1/storefront/review/token_1').send({ overallRating: 0 })
expect(review.status).toBe(400)
expect(marketplaceService.submitReview).not.toHaveBeenCalled()
expect(storefrontService.submitReview).not.toHaveBeenCalled()
})
})
@@ -1,10 +1,10 @@
import { describe, expect, it } from 'vitest'
describe('billing, marketplace, and vehicle integration boundaries', () => {
describe('billing, storefront, and vehicle integration boundaries', () => {
it('documents the Batch-10 DB-backed regression targets for the real integration environment', () => {
expect([
'admin billing invoice lifecycle uses persisted line items and audit logs',
'marketplace company pages enrich vehicles with real availability records',
'storefront company pages enrich vehicles with real availability records',
'vehicle location settings persist through create/update/list flows',
]).toHaveLength(3)
})
@@ -1,14 +1,14 @@
import { describe, expect, it } from 'vitest'
describe('employee, marketplace, and notification integration boundaries', () => {
describe('employee, storefront, and notification integration boundaries', () => {
it('documents the Batch-17 DB-backed integration boundary', () => {
expect({
employeeAuth: 'password reset/login flows require generated Prisma and mail-provider test doubles',
marketplace: 'public booking/review flows require seeded company, vehicle, reservation, and token records',
storefront: 'public booking/review flows require seeded company, vehicle, reservation, and token records',
notifications: 'preference persistence requires notificationPreference composite indexes',
}).toEqual(expect.objectContaining({
employeeAuth: expect.stringContaining('Prisma'),
marketplace: expect.stringContaining('seeded'),
storefront: expect.stringContaining('seeded'),
notifications: expect.stringContaining('composite'),
}))
})
@@ -1,6 +1,6 @@
import { describe, expect, it } from 'vitest'
import { parseBody, parseQuery } from '../../http/validate'
import { marketplaceReservationSchema, paginationSchema } from '../../modules/marketplace/marketplace.schemas'
import { storefrontReservationSchema, paginationSchema } from '../../modules/storefront/storefront.schemas'
import { paySchema } from '../../modules/site/site.schemas'
function reqWith(body: unknown, query: unknown = {}) {
@@ -8,7 +8,7 @@ function reqWith(body: unknown, query: unknown = {}) {
}
describe('public validation boundaries', () => {
it('keeps marketplace pagination coercion consistent with route parsing', () => {
it('keeps storefront pagination coercion consistent with route parsing', () => {
expect(parseQuery(paginationSchema, reqWith({}, { page: '4', pageSize: '25' }))).toEqual({
page: 4,
pageSize: 25,
@@ -24,8 +24,8 @@ describe('public validation boundaries', () => {
}))).toThrow('Invalid enum value')
})
it('requires enough anonymous marketplace reservation identity to create a booking request', () => {
const parsed = parseBody(marketplaceReservationSchema, reqWith({
it('requires enough anonymous storefront reservation identity to create a booking request', () => {
const parsed = parseBody(storefrontReservationSchema, reqWith({
vehicleId: 'ckvvehicle000000000000001',
companySlug: 'atlas-cars',
firstName: 'Aya',