API Architecture

Comprehensive API architecture including RESTful design, server actions, security, and testing strategies.

API Architecture

Welcome to the comprehensive API architecture documentation. This section covers the complete backend API design, implementation patterns, and best practices used in the system.

API Architecture Overview

The API architecture follows modern RESTful principles enhanced with Next.js Server Actions, providing both traditional HTTP APIs and server-side actions for seamless client-server communication. Built with security, performance, and maintainability as core principles.

Key API Characteristics

  • RESTful Design: Resource-based URLs with consistent HTTP methods
  • Type Safety: End-to-end TypeScript for reliability and developer productivity
  • Security First: Multi-layer security with authentication, authorization, and validation
  • Performance Optimized: Efficient data handling and response optimization
  • Testing Coverage: Comprehensive testing strategies for reliability

Core API Components

🌐 RESTful API Design

Comprehensive RESTful principles and design patterns:

  • Resource Design: URL patterns, HTTP methods, and resource organization
  • Response Formats: Consistent JSON structures and error handling
  • Status Codes: Proper HTTP status code usage and conventions
  • Query Parameters: Filtering, pagination, sorting, and search patterns
  • Content Negotiation: Accept headers and response format handling

Server Actions

Next.js Server Actions implementation and patterns:

  • Action Patterns: Form-based and programmatic server actions
  • Validation: Type-safe input validation with Zod schemas
  • Error Handling: Comprehensive error management strategies
  • Optimistic Updates: Client-side optimistic UI patterns
  • Performance: Caching, revalidation, and background processing

🔒 API Security

Multi-layer security implementation:

  • Authentication: JWT tokens, session management, and user verification
  • Authorization: Role-based access control and resource permissions
  • Input Validation: Schema validation, sanitization, and type checking
  • Rate Limiting: Request throttling and abuse prevention
  • Security Headers: CORS, CSP, and other security configurations

🧪 API Testing

Comprehensive testing strategies and patterns:

  • Unit Testing: Business logic and validation testing
  • Integration Testing: End-to-end API endpoint testing
  • Performance Testing: Load testing and response time validation
  • Security Testing: Authentication, authorization, and vulnerability testing
  • Test Utilities: Mocking, fixtures, and test data management

Quick API Reference

Technology Stack

// API Technologies
const apiStack = {
  framework: ['Next.js 14', 'App Router', 'API Routes'],
  serverActions: ['Next.js Server Actions', 'React Server Components'],
  validation: ['Zod', 'TypeScript'],
  authentication: ['Supabase Auth', 'JWT Tokens'],
  database: ['Supabase', 'PostgreSQL', 'Row Level Security'],
  testing: ['Jest', 'Supertest', 'Testing Library']
}

API Design Patterns

  • Resource-Based URLs: /api/products, /api/orders
  • HTTP Method Conventions: GET (read), POST (create), PUT (update), DELETE (remove)
  • Consistent Response Format: { success: boolean, data?: any, error?: any }
  • Type-Safe Validation: Zod schemas for request/response validation
  • Error Handling: Structured error responses with codes and messages

Security Architecture

  • Authentication: Bearer token authentication with JWT
  • Authorization: Role-based permissions with resource-level access control
  • Input Validation: All requests validated against schemas
  • Rate Limiting: IP and user-based request throttling
  • Security Headers: CORS, CSP, and XSS protection

Implementation Examples

Typical API Request Flow

graph TD
    A[Client Request] --> B[Rate Limiting]
    B --> C[Authentication Check]
    C --> D[Authorization Validation]
    D --> E[Input Validation]
    E --> F[Business Logic]
    F --> G[Database Operation]
    G --> H[Response Formatting]
    H --> I[Client Response]

RESTful API Example

// /api/products/route.ts
export async function GET(request: Request) {
  // Authentication & authorization
  const user = await authenticate(request)
  requirePermission(user, 'product:read')
  
  // Query validation
  const query = await validateQuery(request, productQuerySchema)
  
  // Business logic
  const products = await productService.list(query)
  
  // Response
  return Response.json({
    success: true,
    data: {
      items: products.data,
      pagination: products.pagination
    }
  })
}

Server Action Example

// Server Action for product creation
'use server'
export async function createProduct(formData: FormData) {
  // Validation
  const data = createProductSchema.parse({
    name: formData.get('name'),
    price: Number(formData.get('price')),
    // ... other fields
  })
  
  // Business logic
  const product = await productService.create(data)
  
  // Cache revalidation
  revalidatePath('/products')
  
  return { success: true, data: product }
}

API Benefits

Developer Experience

  • Type Safety: Compile-time error detection and IntelliSense support
  • Consistent Patterns: Standardized request/response patterns across all endpoints
  • Excellent Tooling: Built-in validation, testing, and documentation tools
  • Hot Reloading: Instant feedback during development

Performance

  • Server-Side Rendering: Fast initial page loads with Server Actions
  • Optimized Queries: Efficient database operations with proper indexing
  • Caching: Strategic caching at multiple levels for performance
  • Background Processing: Async operations for heavy workloads

Security

  • Defense in Depth: Multiple security layers protecting the API
  • Input Validation: All data validated before processing
  • Access Control: Fine-grained permissions for all resources
  • Audit Logging: Complete audit trail for security monitoring

Scalability

  • Stateless Design: Easy horizontal scaling of API servers
  • Database Optimization: Efficient queries and connection pooling
  • Rate Limiting: Protection against abuse and overload
  • Monitoring: Comprehensive observability for performance tuning

Getting Started with API Development

For Backend Developers

  1. RESTful Principles: Start with RESTful API Design
  2. Server Actions: Learn Server Actions patterns
  3. Security Implementation: Study API Security
  4. Testing Strategies: Implement API Testing

For Frontend Developers

  1. API Consumption: Understand RESTful endpoints and response formats
  2. Server Actions: Learn to use Server Actions in components
  3. Error Handling: Implement proper error handling for API calls
  4. Type Safety: Utilize TypeScript interfaces for API contracts

For DevOps Engineers

  1. API Monitoring: Set up performance and error monitoring
  2. Security Configuration: Implement security headers and policies
  3. Rate Limiting: Configure appropriate rate limiting rules
  4. Load Testing: Establish performance benchmarks and testing

Complementary Architecture Docs

Operational Guides


This API architecture documentation provides the foundation for building secure, scalable, and maintainable backend services. Each section builds upon the others to create a comprehensive API development guide.

API Endpoint Structure

api/
├── inventory/              # Inventory management
│   ├── GET /               # Get inventory levels
│   ├── POST /movements     # Record stock movement
│   ├── POST /adjustments   # Perform adjustments
│   ├── GET /low-stock      # Low stock alerts
│   └── GET /analytics      # Inventory analytics
├── orders/                 # Order management
│   ├── purchase-orders/    # Purchase order endpoints
│   │   ├── GET /           # List purchase orders
│   │   ├── POST /          # Create purchase order
│   │   ├── GET /{id}       # Get purchase order
│   │   ├── PUT /{id}       # Update purchase order
│   │   └── POST /{id}/receive # Receive items
│   └── sales-orders/       # Sales order endpoints
│       ├── GET /           # List sales orders
│       ├── POST /          # Create sales order
│       ├── GET /{id}       # Get sales order
│       ├── PUT /{id}       # Update sales order
│       └── POST /{id}/ship # Ship order
├── warehouse/              # Warehouse management
│   ├── GET /               # List warehouses
│   ├── POST /              # Create warehouse
│   ├── GET /{id}           # Get warehouse details
│   ├── PUT /{id}           # Update warehouse
│   └── POST /transfers     # Create transfer
├── suppliers/              # Supplier management
│   ├── GET /               # List suppliers
│   ├── POST /              # Create supplier
│   ├── GET /{id}           # Get supplier details
│   └── PUT /{id}           # Update supplier
├── customers/              # Customer management
│   ├── GET /               # List customers
│   ├── POST /              # Create customer
│   ├── GET /{id}           # Get customer details
│   └── PUT /{id}           # Update customer
├── users/                  # User management
│   ├── GET /               # List users
│   ├── POST /              # Create user
│   ├── GET /{id}           # Get user details
│   └── PUT /{id}           # Update user
└── analytics/              # Analytics and reporting
    ├── dashboard/          # Dashboard metrics
    ├── inventory/          # Inventory reports
    ├── sales/              # Sales reports
    └── financial/          # Financial reports

## Request/Response Patterns

### Standard Response Format

```typescript
// Success Response
interface ApiResponse<T> {
  success: true;
  data: T;
  message?: string;
  meta?: {
    total?: number;
    page?: number;
    limit?: number;
    hasNext?: boolean;
    hasPrev?: boolean;
  };
}

// Error Response
interface ApiError {
  success: false;
  error: {
    code: string;
    message: string;
    details?: any;
    field?: string; // For validation errors
  };
}

Example API Responses

Success Response

{
  "success": true,
  "data": [
    {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "Widget A",
      "sku": "WGT-001",
      "price": 29.99,
      "category": "Electronics"
    }
  ],
  "meta": {
    "total": 150,
    "page": 1,
    "limit": 20,
    "hasNext": true,
    "hasPrev": false
  }
}

Error Response

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid product data",
    "details": {
      "name": "Product name is required",
      "sku": "SKU must be unique"
    }
  }
}

API Implementation

Route Handler Structure

// app/api/products/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';
import { validateAuth } from '@/lib/auth';
import { productSchema } from '@/lib/validations';
import { productService } from '@/lib/services';

// GET /api/products
export async function GET(request: NextRequest) {
  try {
    // Authentication
    const user = await validateAuth(request);
    
    // Extract query parameters
    const { searchParams } = new URL(request.url);
    const page = Number(searchParams.get('page')) || 1;
    const limit = Number(searchParams.get('limit')) || 20;
    const search = searchParams.get('search') || '';
    const category = searchParams.get('category') || '';
    
    // Authorization check
    if (!user.permissions.includes('products:read')) {
      return NextResponse.json(
        { 
          success: false, 
          error: { 
            code: 'FORBIDDEN', 
            message: 'Insufficient permissions' 
          } 
        },
        { status: 403 }
      );
    }
    
    // Fetch data
    const result = await productService.getProducts({
      page,
      limit,
      search,
      category,
      warehouseId: user.warehouseId,
    });
    
    return NextResponse.json({
      success: true,
      data: result.products,
      meta: {
        total: result.total,
        page,
        limit,
        hasNext: page * limit < result.total,
        hasPrev: page > 1,
      },
    });
    
  } catch (error) {
    console.error('GET /api/products error:', error);
    
    return NextResponse.json(
      {
        success: false,
        error: {
          code: 'INTERNAL_ERROR',
          message: 'Failed to fetch products',
        },
      },
      { status: 500 }
    );
  }
}

// POST /api/products
export async function POST(request: NextRequest) {
  try {
    // Authentication
    const user = await validateAuth(request);
    
    // Authorization check
    if (!user.permissions.includes('products:create')) {
      return NextResponse.json(
        { 
          success: false, 
          error: { 
            code: 'FORBIDDEN', 
            message: 'Insufficient permissions' 
          } 
        },
        { status: 403 }
      );
    }
    
    // Parse and validate request body
    const body = await request.json();
    const validatedData = productSchema.parse(body);
    
    // Create product
    const product = await productService.createProduct({
      ...validatedData,
      createdBy: user.id,
    });
    
    return NextResponse.json(
      {
        success: true,
        data: product,
        message: 'Product created successfully',
      },
      { status: 201 }
    );
    
  } catch (error) {
    if (error instanceof z.ZodError) {
      return NextResponse.json(
        {
          success: false,
          error: {
            code: 'VALIDATION_ERROR',
            message: 'Invalid product data',
            details: error.flatten().fieldErrors,
          },
        },
        { status: 400 }
      );
    }
    
    console.error('POST /api/products error:', error);
    
    return NextResponse.json(
      {
        success: false,
        error: {
          code: 'INTERNAL_ERROR',
          message: 'Failed to create product',
        },
      },
      { status: 500 }
    );
  }
}

Server Actions

Smart Shelf also uses Next.js Server Actions for form handling and mutations:

// lib/actions/products.ts
'use server';

import { revalidatePath } from 'next/cache';
import { redirect } from 'next/navigation';
import { z } from 'zod';
import { getCurrentUser } from '@/lib/auth';
import { productSchema } from '@/lib/validations';
import { productService } from '@/lib/services';

export async function createProductAction(formData: FormData) {
  // Authentication
  const user = await getCurrentUser();
  if (!user) {
    throw new Error('Authentication required');
  }
  
  // Authorization
  if (!user.permissions.includes('products:create')) {
    throw new Error('Insufficient permissions');
  }
  
  // Validate form data
  const rawData = {
    name: formData.get('name'),
    sku: formData.get('sku'),
    description: formData.get('description'),
    categoryId: formData.get('categoryId'),
    costPrice: Number(formData.get('costPrice')),
    sellingPrice: Number(formData.get('sellingPrice')),
  };
  
  const validatedData = productSchema.parse(rawData);
  
  try {
    // Create product
    const product = await productService.createProduct({
      ...validatedData,
      createdBy: user.id,
    });
    
    // Revalidate relevant pages
    revalidatePath('/products');
    revalidatePath('/inventory');
    
    // Redirect to product page
    redirect(`/products/${product.id}`);
    
  } catch (error) {
    throw new Error('Failed to create product');
  }
}

export async function updateProductAction(
  productId: string, 
  formData: FormData
) {
  const user = await getCurrentUser();
  if (!user) {
    throw new Error('Authentication required');
  }
  
  if (!user.permissions.includes('products:update')) {
    throw new Error('Insufficient permissions');
  }
  
  // Validate and update product
  const rawData = {
    name: formData.get('name'),
    description: formData.get('description'),
    costPrice: Number(formData.get('costPrice')),
    sellingPrice: Number(formData.get('sellingPrice')),
  };
  
  const validatedData = productSchema.partial().parse(rawData);
  
  try {
    await productService.updateProduct(productId, {
      ...validatedData,
      updatedBy: user.id,
    });
    
    revalidatePath(`/products/${productId}`);
    revalidatePath('/products');
    
  } catch (error) {
    throw new Error('Failed to update product');
  }
}

Authentication & Authorization

JWT Token Validation

// lib/auth/validate.ts
import { jwtVerify } from 'jose';
import { NextRequest } from 'next/server';
import { userService } from '@/lib/services';

export async function validateAuth(request: NextRequest) {
  try {
    // Extract token from Authorization header
    const authHeader = request.headers.get('authorization');
    if (!authHeader?.startsWith('Bearer ')) {
      throw new Error('Missing or invalid authorization header');
    }
    
    const token = authHeader.substring(7);
    
    // Verify JWT token
    const secret = new TextEncoder().encode(process.env.JWT_SECRET);
    const { payload } = await jwtVerify(token, secret);
    
    // Get user details
    const user = await userService.getUserById(payload.sub as string);
    if (!user || !user.isActive) {
      throw new Error('User not found or inactive');
    }
    
    return user;
    
  } catch (error) {
    throw new Error('Invalid or expired token');
  }
}

Role-Based Authorization

// lib/auth/permissions.ts
export const PERMISSIONS = {
  // Product permissions
  'products:read': ['admin', 'manager', 'staff'],
  'products:create': ['admin', 'manager'],
  'products:update': ['admin', 'manager'],
  'products:delete': ['admin'],
  
  // Inventory permissions
  'inventory:read': ['admin', 'manager', 'staff'],
  'inventory:adjust': ['admin', 'manager'],
  'inventory:transfer': ['admin', 'manager'],
  
  // Order permissions
  'orders:read': ['admin', 'manager', 'staff'],
  'orders:create': ['admin', 'manager', 'staff'],
  'orders:approve': ['admin', 'manager'],
  
  // User permissions
  'users:read': ['admin'],
  'users:create': ['admin'],
  'users:update': ['admin'],
  'users:delete': ['admin'],
} as const;

export function hasPermission(userRole: string, permission: string): boolean {
  const allowedRoles = PERMISSIONS[permission as keyof typeof PERMISSIONS];
  return allowedRoles?.includes(userRole as any) ?? false;
}

export function requirePermission(user: User, permission: string) {
  if (!hasPermission(user.role, permission)) {
    throw new Error(`Permission denied: ${permission}`);
  }
}

Input Validation

Zod Schemas

// lib/validations/product.ts
import { z } from 'zod';

export const productSchema = z.object({
  name: z.string()
    .min(1, 'Product name is required')
    .max(255, 'Product name is too long'),
  
  description: z.string()
    .max(1000, 'Description is too long')
    .optional(),
  
  sku: z.string()
    .min(1, 'SKU is required')
    .max(50, 'SKU is too long')
    .regex(/^[A-Z0-9-]+$/, 'SKU must contain only uppercase letters, numbers, and hyphens'),
  
  categoryId: z.string()
    .uuid('Invalid category ID'),
  
  brand: z.string()
    .max(100, 'Brand name is too long')
    .optional(),
  
  unitOfMeasure: z.enum(['piece', 'kg', 'liter', 'meter', 'box', 'pack']),
  
  costPrice: z.number()
    .min(0, 'Cost price must be positive')
    .max(999999.99, 'Cost price is too high'),
  
  sellingPrice: z.number()
    .min(0, 'Selling price must be positive')
    .max(999999.99, 'Selling price is too high'),
  
  minStockLevel: z.number()
    .int('Minimum stock level must be an integer')
    .min(0, 'Minimum stock level must be positive')
    .optional(),
  
  maxStockLevel: z.number()
    .int('Maximum stock level must be an integer')
    .min(0, 'Maximum stock level must be positive')
    .optional(),
  
  isActive: z.boolean().default(true),
});

export const productUpdateSchema = productSchema.partial();

export type ProductInput = z.infer<typeof productSchema>;
export type ProductUpdateInput = z.infer<typeof productUpdateSchema>;

Request Validation Middleware

// lib/middleware/validation.ts
import { NextRequest, NextResponse } from 'next/server';
import { z } from 'zod';

export function withValidation<T>(schema: z.ZodSchema<T>) {
  return function(handler: (req: NextRequest, data: T) => Promise<NextResponse>) {
    return async function(req: NextRequest) {
      try {
        const body = await req.json();
        const validatedData = schema.parse(body);
        return handler(req, validatedData);
      } catch (error) {
        if (error instanceof z.ZodError) {
          return NextResponse.json(
            {
              success: false,
              error: {
                code: 'VALIDATION_ERROR',
                message: 'Invalid request data',
                details: error.flatten().fieldErrors,
              },
            },
            { status: 400 }
          );
        }
        
        return NextResponse.json(
          {
            success: false,
            error: {
              code: 'INTERNAL_ERROR',
              message: 'Request processing failed',
            },
          },
          { status: 500 }
        );
      }
    };
  };
}

// Usage
export const POST = withValidation(productSchema)(async (req, data) => {
  // Handler with validated data
  const product = await productService.createProduct(data);
  return NextResponse.json({ success: true, data: product });
});

Error Handling

Centralized Error Handler

// lib/errors/handler.ts
import { NextResponse } from 'next/server';
import { z } from 'zod';

export class ApiError extends Error {
  constructor(
    public code: string,
    public message: string,
    public statusCode: number = 500,
    public details?: any
  ) {
    super(message);
    this.name = 'ApiError';
  }
}

export function handleApiError(error: unknown): NextResponse {
  console.error('API Error:', error);
  
  // Validation errors
  if (error instanceof z.ZodError) {
    return NextResponse.json(
      {
        success: false,
        error: {
          code: 'VALIDATION_ERROR',
          message: 'Invalid request data',
          details: error.flatten().fieldErrors,
        },
      },
      { status: 400 }
    );
  }
  
  // Custom API errors
  if (error instanceof ApiError) {
    return NextResponse.json(
      {
        success: false,
        error: {
          code: error.code,
          message: error.message,
          details: error.details,
        },
      },
      { status: error.statusCode }
    );
  }
  
  // Database errors
  if (error instanceof Error && error.message.includes('unique constraint')) {
    return NextResponse.json(
      {
        success: false,
        error: {
          code: 'DUPLICATE_ERROR',
          message: 'Record already exists',
        },
      },
      { status: 409 }
    );
  }
  
  // Generic errors
  return NextResponse.json(
    {
      success: false,
      error: {
        code: 'INTERNAL_ERROR',
        message: 'An unexpected error occurred',
      },
    },
    { status: 500 }
  );
}

// Usage in route handlers
export async function GET(request: NextRequest) {
  try {
    // Route logic
  } catch (error) {
    return handleApiError(error);
  }
}

Rate Limiting

API Rate Limiting

// lib/middleware/rate-limit.ts
import { NextRequest, NextResponse } from 'next/server';

interface RateLimitConfig {
  windowMs: number;
  maxRequests: number;
  keyGenerator?: (req: NextRequest) => string;
}

const requestCounts = new Map<string, { count: number; resetTime: number }>();

export function rateLimit(config: RateLimitConfig) {
  return function(handler: (req: NextRequest) => Promise<NextResponse>) {
    return async function(req: NextRequest) {
      const key = config.keyGenerator ? 
        config.keyGenerator(req) : 
        req.ip || 'default';
      
      const now = Date.now();
      const windowStart = now - config.windowMs;
      
      // Get or create rate limit data
      let rateLimitData = requestCounts.get(key);
      
      if (!rateLimitData || rateLimitData.resetTime < windowStart) {
        rateLimitData = { count: 0, resetTime: now + config.windowMs };
        requestCounts.set(key, rateLimitData);
      }
      
      // Check if limit exceeded
      if (rateLimitData.count >= config.maxRequests) {
        return NextResponse.json(
          {
            success: false,
            error: {
              code: 'RATE_LIMIT_EXCEEDED',
              message: 'Too many requests',
            },
          },
          { 
            status: 429,
            headers: {
              'Retry-After': String(Math.ceil((rateLimitData.resetTime - now) / 1000)),
            },
          }
        );
      }
      
      // Increment count and proceed
      rateLimitData.count++;
      
      return handler(req);
    };
  };
}

// Usage
export const GET = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  maxRequests: 100,
  keyGenerator: (req) => req.headers.get('x-forwarded-for') || req.ip || 'default',
})(async (req) => {
  // Route handler
});

API Testing

Unit Tests for API Routes

// __tests__/api/products.test.ts
import { NextRequest } from 'next/server';
import { GET, POST } from '@/app/api/products/route';

// Mock dependencies
jest.mock('@/lib/auth');
jest.mock('@/lib/services');

describe('/api/products', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });
  
  describe('GET', () => {
    it('should return products for authenticated user', async () => {
      // Mock authentication
      (validateAuth as jest.Mock).mockResolvedValue({
        id: 'user-1',
        permissions: ['products:read'],
        warehouseId: 'warehouse-1',
      });
      
      // Mock service
      (productService.getProducts as jest.Mock).mockResolvedValue({
        products: [
          { id: '1', name: 'Product 1', sku: 'P001' },
          { id: '2', name: 'Product 2', sku: 'P002' },
        ],
        total: 2,
      });
      
      const request = new NextRequest('http://localhost/api/products');
      const response = await GET(request);
      const data = await response.json();
      
      expect(response.status).toBe(200);
      expect(data.success).toBe(true);
      expect(data.data).toHaveLength(2);
      expect(data.meta.total).toBe(2);
    });
    
    it('should return 403 for insufficient permissions', async () => {
      (validateAuth as jest.Mock).mockResolvedValue({
        id: 'user-1',
        permissions: [], // No permissions
      });
      
      const request = new NextRequest('http://localhost/api/products');
      const response = await GET(request);
      const data = await response.json();
      
      expect(response.status).toBe(403);
      expect(data.success).toBe(false);
      expect(data.error.code).toBe('FORBIDDEN');
    });
  });
  
  describe('POST', () => {
    it('should create product with valid data', async () => {
      (validateAuth as jest.Mock).mockResolvedValue({
        id: 'user-1',
        permissions: ['products:create'],
      });
      
      (productService.createProduct as jest.Mock).mockResolvedValue({
        id: '1',
        name: 'New Product',
        sku: 'NP001',
      });
      
      const request = new NextRequest('http://localhost/api/products', {
        method: 'POST',
        body: JSON.stringify({
          name: 'New Product',
          sku: 'NP001',
          categoryId: 'cat-1',
          costPrice: 10.00,
          sellingPrice: 15.00,
          unitOfMeasure: 'piece',
        }),
      });
      
      const response = await POST(request);
      const data = await response.json();
      
      expect(response.status).toBe(201);
      expect(data.success).toBe(true);
      expect(data.data.name).toBe('New Product');
    });
  });
});

This API architecture ensures secure, scalable, and maintainable backend services for the Smart Shelf application.