fix: remove vendorCode from vendor API paths

Vendor API endpoints use JWT authentication, not URL path parameters.
The vendorCode should only be used for page URLs (navigation), not API calls.

Fixed API paths in 10 vendor JS files:
- analytics.js, customers.js, inventory.js, notifications.js
- order-detail.js, orders.js, products.js, profile.js
- settings.js, team.js

Added architecture rule JS-014 to prevent this pattern from recurring.
Added validation check _check_vendor_api_paths to validate_architecture.py.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-02 21:49:24 +01:00
parent c87bdfa129
commit 34d115dc58
12 changed files with 131 additions and 43 deletions

View File

@@ -107,7 +107,7 @@ function vendorAnalytics() {
*/
async fetchAnalytics() {
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/analytics?period=${this.period}`);
const response = await apiClient.get(`/vendor/analytics?period=${this.period}`);
return response;
} catch (error) {
// Analytics might require feature access
@@ -124,7 +124,7 @@ function vendorAnalytics() {
*/
async fetchStats() {
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/dashboard/stats`);
const response = await apiClient.get(`/vendor/dashboard/stats`);
return {
total_products: response.catalog?.total_products || 0,
active_products: response.catalog?.active_products || 0,

View File

@@ -148,7 +148,7 @@ function vendorCustomers() {
params.append('status', this.filters.status);
}
const response = await apiClient.get(`/vendor/${this.vendorCode}/customers?${params.toString()}`);
const response = await apiClient.get(`/vendor/customers?${params.toString()}`);
this.customers = response.customers || [];
this.pagination.total = response.total || 0;
@@ -212,7 +212,7 @@ function vendorCustomers() {
async viewCustomer(customer) {
this.loading = true;
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/customers/${customer.id}`);
const response = await apiClient.get(`/vendor/customers/${customer.id}`);
this.selectedCustomer = response;
this.showDetailModal = true;
vendorCustomersLog.info('Loaded customer details:', customer.id);
@@ -230,7 +230,7 @@ function vendorCustomers() {
async viewCustomerOrders(customer) {
this.loading = true;
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/customers/${customer.id}/orders`);
const response = await apiClient.get(`/vendor/customers/${customer.id}/orders`);
this.selectedCustomer = customer;
this.customerOrders = response.orders || [];
this.showOrdersModal = true;

View File

@@ -182,7 +182,7 @@ function vendorInventory() {
params.append('low_stock', this.filters.low_stock);
}
const response = await apiClient.get(`/vendor/${this.vendorCode}/inventory?${params.toString()}`);
const response = await apiClient.get(`/vendor/inventory?${params.toString()}`);
this.inventory = response.items || [];
this.pagination.total = response.total || 0;
@@ -286,7 +286,7 @@ function vendorInventory() {
this.saving = true;
try {
await apiClient.post(`/vendor/${this.vendorCode}/inventory/adjust`, {
await apiClient.post(`/vendor/inventory/adjust`, {
product_id: this.selectedItem.product_id,
location: this.selectedItem.location,
quantity: this.adjustForm.quantity,
@@ -317,7 +317,7 @@ function vendorInventory() {
this.saving = true;
try {
await apiClient.post(`/vendor/${this.vendorCode}/inventory/set`, {
await apiClient.post(`/vendor/inventory/set`, {
product_id: this.selectedItem.product_id,
location: this.selectedItem.location,
quantity: this.setForm.quantity
@@ -452,7 +452,7 @@ function vendorInventory() {
const item = this.inventory.find(i => i.id === itemId);
if (item) {
try {
await apiClient.post(`/vendor/${this.vendorCode}/inventory/adjust`, {
await apiClient.post(`/vendor/inventory/adjust`, {
product_id: item.product_id,
location: item.location,
quantity: this.bulkAdjustForm.quantity,

View File

@@ -95,7 +95,7 @@ function vendorNotifications() {
params.append('unread_only', 'true');
}
const response = await apiClient.get(`/vendor/${this.vendorCode}/notifications?${params}`);
const response = await apiClient.get(`/vendor/notifications?${params}`);
this.notifications = response.notifications || [];
this.stats.total = response.total || 0;
@@ -115,7 +115,7 @@ function vendorNotifications() {
*/
async markAsRead(notification) {
try {
await apiClient.put(`/vendor/${this.vendorCode}/notifications/${notification.id}/read`);
await apiClient.put(`/vendor/notifications/${notification.id}/read`);
// Update local state
notification.is_read = true;
@@ -133,7 +133,7 @@ function vendorNotifications() {
*/
async markAllAsRead() {
try {
await apiClient.put(`/vendor/${this.vendorCode}/notifications/mark-all-read`);
await apiClient.put(`/vendor/notifications/mark-all-read`);
// Update local state
this.notifications.forEach(n => n.is_read = true);
@@ -155,7 +155,7 @@ function vendorNotifications() {
}
try {
await apiClient.delete(`/vendor/${this.vendorCode}/notifications/${notificationId}`);
await apiClient.delete(`/vendor/notifications/${notificationId}`);
// Remove from local state
const wasUnread = this.notifications.find(n => n.id === notificationId && !n.is_read);
@@ -177,7 +177,7 @@ function vendorNotifications() {
*/
async openSettingsModal() {
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/notifications/settings`);
const response = await apiClient.get(`/vendor/notifications/settings`);
this.settingsForm = {
email_notifications: response.email_notifications !== false,
in_app_notifications: response.in_app_notifications !== false
@@ -194,7 +194,7 @@ function vendorNotifications() {
*/
async saveSettings() {
try {
await apiClient.put(`/vendor/${this.vendorCode}/notifications/settings`, this.settingsForm);
await apiClient.put(`/vendor/notifications/settings`, this.settingsForm);
Utils.showToast('Notification settings saved', 'success');
this.showSettingsModal = false;
} catch (error) {

View File

@@ -94,7 +94,7 @@ function vendorOrderDetail() {
try {
// Load order details
const orderResponse = await apiClient.get(
`/vendor/${this.vendorCode}/orders/${this.orderId}`
`/vendor/orders/${this.orderId}`
);
this.order = orderResponse;
this.newStatus = this.order.status;
@@ -121,7 +121,7 @@ function vendorOrderDetail() {
async loadShipmentStatus() {
try {
const response = await apiClient.get(
`/vendor/${this.vendorCode}/orders/${this.orderId}/shipment-status`
`/vendor/orders/${this.orderId}/shipment-status`
);
this.shipmentStatus = response;
orderDetailLog.info('Loaded shipment status:', response);
@@ -138,7 +138,7 @@ function vendorOrderDetail() {
try {
// Search for invoices linked to this order
const response = await apiClient.get(
`/vendor/${this.vendorCode}/invoices?order_id=${this.orderId}&limit=1`
`/vendor/invoices?order_id=${this.orderId}&limit=1`
);
if (response.invoices && response.invoices.length > 0) {
this.invoice = response.invoices[0];
@@ -223,7 +223,7 @@ function vendorOrderDetail() {
}
await apiClient.put(
`/vendor/${this.vendorCode}/orders/${this.orderId}/status`,
`/vendor/orders/${this.orderId}/status`,
payload
);
@@ -255,7 +255,7 @@ function vendorOrderDetail() {
this.saving = true;
try {
await apiClient.post(
`/vendor/${this.vendorCode}/orders/${this.orderId}/items/${itemId}/ship`,
`/vendor/orders/${this.orderId}/items/${itemId}/ship`,
{}
);
@@ -281,7 +281,7 @@ function vendorOrderDetail() {
for (const item of unshippedItems) {
await apiClient.post(
`/vendor/${this.vendorCode}/orders/${this.orderId}/items/${item.item_id}/ship`,
`/vendor/orders/${this.orderId}/items/${item.item_id}/ship`,
{}
);
}
@@ -294,7 +294,7 @@ function vendorOrderDetail() {
}
await apiClient.put(
`/vendor/${this.vendorCode}/orders/${this.orderId}/status`,
`/vendor/orders/${this.orderId}/status`,
payload
);
@@ -319,7 +319,7 @@ function vendorOrderDetail() {
this.creatingInvoice = true;
try {
const response = await apiClient.post(
`/vendor/${this.vendorCode}/invoices`,
`/vendor/invoices`,
{ order_id: this.orderId }
);

View File

@@ -185,7 +185,7 @@ function vendorOrders() {
params.append('date_to', this.filters.date_to);
}
const response = await apiClient.get(`/vendor/${this.vendorCode}/orders?${params.toString()}`);
const response = await apiClient.get(`/vendor/orders?${params.toString()}`);
this.orders = response.orders || [];
this.pagination.total = response.total || 0;
@@ -273,7 +273,7 @@ function vendorOrders() {
this.saving = true;
try {
await apiClient.put(`/vendor/${this.vendorCode}/orders/${this.selectedOrder.id}/status`, {
await apiClient.put(`/vendor/orders/${this.selectedOrder.id}/status`, {
status: this.newStatus
});
@@ -423,7 +423,7 @@ function vendorOrders() {
let successCount = 0;
for (const orderId of this.selectedOrders) {
try {
await apiClient.put(`/vendor/${this.vendorCode}/orders/${orderId}/status`, {
await apiClient.put(`/vendor/orders/${orderId}/status`, {
status: this.bulkStatus
});
successCount++;

View File

@@ -166,7 +166,7 @@ function vendorProducts() {
params.append('is_featured', this.filters.featured === 'true');
}
const response = await apiClient.get(`/vendor/${this.vendorCode}/products?${params.toString()}`);
const response = await apiClient.get(`/vendor/products?${params.toString()}`);
this.products = response.products || [];
this.pagination.total = response.total || 0;
@@ -227,7 +227,7 @@ function vendorProducts() {
async toggleActive(product) {
this.saving = true;
try {
await apiClient.put(`/vendor/${this.vendorCode}/products/${product.id}/toggle-active`);
await apiClient.put(`/vendor/products/${product.id}/toggle-active`);
product.is_active = !product.is_active;
Utils.showToast(
product.is_active ? 'Product activated' : 'Product deactivated',
@@ -248,7 +248,7 @@ function vendorProducts() {
async toggleFeatured(product) {
this.saving = true;
try {
await apiClient.put(`/vendor/${this.vendorCode}/products/${product.id}/toggle-featured`);
await apiClient.put(`/vendor/products/${product.id}/toggle-featured`);
product.is_featured = !product.is_featured;
Utils.showToast(
product.is_featured ? 'Product marked as featured' : 'Product unmarked as featured',
@@ -287,7 +287,7 @@ function vendorProducts() {
this.saving = true;
try {
await apiClient.delete(`/vendor/${this.vendorCode}/products/${this.selectedProduct.id}`);
await apiClient.delete(`/vendor/products/${this.selectedProduct.id}`);
Utils.showToast('Product deleted successfully', 'success');
vendorProductsLog.info('Deleted product:', this.selectedProduct.id);
@@ -410,7 +410,7 @@ function vendorProducts() {
for (const productId of this.selectedProducts) {
const product = this.products.find(p => p.id === productId);
if (product && !product.is_active) {
await apiClient.put(`/vendor/${this.vendorCode}/products/${productId}/toggle-active`);
await apiClient.put(`/vendor/products/${productId}/toggle-active`);
product.is_active = true;
successCount++;
}
@@ -438,7 +438,7 @@ function vendorProducts() {
for (const productId of this.selectedProducts) {
const product = this.products.find(p => p.id === productId);
if (product && product.is_active) {
await apiClient.put(`/vendor/${this.vendorCode}/products/${productId}/toggle-active`);
await apiClient.put(`/vendor/products/${productId}/toggle-active`);
product.is_active = false;
successCount++;
}
@@ -466,7 +466,7 @@ function vendorProducts() {
for (const productId of this.selectedProducts) {
const product = this.products.find(p => p.id === productId);
if (product && !product.is_featured) {
await apiClient.put(`/vendor/${this.vendorCode}/products/${productId}/toggle-featured`);
await apiClient.put(`/vendor/products/${productId}/toggle-featured`);
product.is_featured = true;
successCount++;
}
@@ -494,7 +494,7 @@ function vendorProducts() {
for (const productId of this.selectedProducts) {
const product = this.products.find(p => p.id === productId);
if (product && product.is_featured) {
await apiClient.put(`/vendor/${this.vendorCode}/products/${productId}/toggle-featured`);
await apiClient.put(`/vendor/products/${productId}/toggle-featured`);
product.is_featured = false;
successCount++;
}
@@ -528,7 +528,7 @@ function vendorProducts() {
try {
let successCount = 0;
for (const productId of this.selectedProducts) {
await apiClient.delete(`/vendor/${this.vendorCode}/products/${productId}`);
await apiClient.delete(`/vendor/products/${productId}`);
successCount++;
}
Utils.showToast(`${successCount} product(s) deleted`, 'success');

View File

@@ -78,7 +78,7 @@ function vendorProfile() {
this.error = '';
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/profile`);
const response = await apiClient.get(`/vendor/profile`);
this.profile = response;
this.form = {
@@ -159,7 +159,7 @@ function vendorProfile() {
this.saving = true;
try {
await apiClient.put(`/vendor/${this.vendorCode}/profile`, this.form);
await apiClient.put(`/vendor/profile`, this.form);
Utils.showToast('Profile updated successfully', 'success');
vendorProfileLog.info('Profile updated');

View File

@@ -92,7 +92,7 @@ function vendorSettings() {
this.error = '';
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/settings`);
const response = await apiClient.get(`/vendor/settings`);
this.settings = response;
@@ -131,7 +131,7 @@ function vendorSettings() {
async saveMarketplaceSettings() {
this.saving = true;
try {
await apiClient.put(`/vendor/${this.vendorCode}/settings/marketplace`, this.marketplaceForm);
await apiClient.put(`/vendor/settings/marketplace`, this.marketplaceForm);
Utils.showToast('Marketplace settings saved', 'success');
vendorSettingsLog.info('Marketplace settings updated');

View File

@@ -100,7 +100,7 @@ function vendorTeam() {
this.error = '';
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/team/members?include_inactive=true`);
const response = await apiClient.get(`/vendor/team/members?include_inactive=true`);
this.members = response.members || [];
this.stats = {
@@ -123,7 +123,7 @@ function vendorTeam() {
*/
async loadRoles() {
try {
const response = await apiClient.get(`/vendor/${this.vendorCode}/team/roles`);
const response = await apiClient.get(`/vendor/team/roles`);
this.roles = response.roles || [];
vendorTeamLog.info('Loaded roles:', this.roles.length);
} catch (error) {
@@ -155,7 +155,7 @@ function vendorTeam() {
this.saving = true;
try {
await apiClient.post(`/vendor/${this.vendorCode}/team/invite`, this.inviteForm);
await apiClient.post(`/vendor/team/invite`, this.inviteForm);
Utils.showToast('Invitation sent successfully', 'success');
vendorTeamLog.info('Invitation sent to:', this.inviteForm.email);
@@ -225,7 +225,7 @@ function vendorTeam() {
this.saving = true;
try {
await apiClient.delete(`/vendor/${this.vendorCode}/team/members/${this.selectedMember.user_id}`);
await apiClient.delete(`/vendor/team/members/${this.selectedMember.user_id}`);
Utils.showToast('Team member removed', 'success');
vendorTeamLog.info('Removed team member:', this.selectedMember.user_id);