Code Structure Guide
This guide explains how the University Inventory Management System code is organized, making it easy for developers to understand and extend the application.
Project Architecture Overview
The system follows a modern full-stack TypeScript architecture with clear separation between frontend, backend, and shared components:
LUStores/
├── .github/ # GitHub Actions CI/CD workflows
│ └── workflows/
│ └── main.yml # Comprehensive CI/CD pipeline
├── client/ # React frontend application
│ ├── src/
│ │ ├── components/ # Reusable UI components
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utility libraries
│ │ ├── pages/ # Page components (routes)
│ │ ├── App.tsx # Main application component
│ │ ├── main.tsx # Application entry point
│ │ └── index.css # Global styles and CSS variables
│ ├── index.html # HTML template
│ └── tsconfig.json # Client TypeScript config
├── server/ # Express.js backend
│ ├── __tests__/ # Jest test suites
│ ├── routes.ts # API route definitions
│ ├── storage.ts # Database operations layer
│ ├── dbConfig.ts # Database connection setup
│ ├── dbInit.ts # Database initialization
│ ├── localAuth.ts # Email/password authentication
│ ├── universitySso.ts # SAML SSO integration
│ ├── permissions.ts # Role-based access control
│ ├── backup.ts # Database backup system
│ ├── invoiceParser.ts # PDF invoice processing
│ └── index.ts # Server entry point
├── shared/ # Shared TypeScript definitions
│ └── schema.ts # Database schema and types
├── docker/ # Docker configurations
│ └── replit-auth/ # Local authentication service
├── performance-tests/ # k6 load testing scripts
│ └── load-test.js # Performance test definitions
├── scripts/ # Build and deployment scripts
│ ├── init-database.ts # Database initialization
│ ├── generate-migration.ts # Database migration generator
│ └── test-automation.sh # Test automation scripts
├── docs/ # Sphinx documentation
│ ├── admin/ # Administration guides
│ ├── api/ # API reference
│ ├── developer/ # Developer documentation
│ ├── deployment/ # Deployment guides
│ ├── reference/ # Technical reference
│ ├── tutorials/ # User tutorials
│ └── user-guide/ # User documentation
├── tests/ # Additional test files
├── migrations/ # Database migration files
├── coverage/ # Test coverage reports
├── reports/ # Generated test reports
├── logs/ # Application logs
├── docker-compose.yml # Development environment
├── docker-compose.prod.yml # Production environment
├── Dockerfile # Container definition
├── package.json # Project dependencies
├── tsconfig.json # Root TypeScript config
├── tsconfig.server.json # Server TypeScript config
├── vite.config.ts # Frontend build configuration
├── tailwind.config.ts # Tailwind CSS configuration
└── jest.config.js # Jest testing configuration
Frontend Architecture (client/)
React Application Structure
Core Application Files:
client/src/App.tsxMain application component that handles routing and authentication state. Contains the router logic that shows different pages based on user authentication status.
client/src/main.tsxApplication entry point that sets up React Query, theming, and renders the main App component.
Component Organization:
client/src/components/Reusable UI components organized by functionality:
ui/- Base UI components (buttons, forms, cards) from shadcn/uiInventoryTable.tsx- Main inventory display componentItemModal.tsx- Add/edit item dialog with location/unit tracking [ADDED 2025]Sidebar.tsx- Navigation sidebar with role-based menu itemsTopBar.tsx- Header with user profile and notificationsStatsCards.tsx- Dashboard statistics displayDatabaseERD.tsx- Interactive database schema diagram [ADDED 2025]DatabaseSchemaManager.tsx- Migration guide and schema documentation [ADDED 2025]
Page Components:
client/src/pages/Each page represents a route in the application:
Landing.tsx- Public landing page for unauthenticated usersLogin.tsx- Authentication interface (both SSO and local)Dashboard.tsx- Main dashboard with statistics and overviewInventory.tsx- Inventory management with search, filters, location/unit trackingSalesQuotes.tsx- Sales and quotes with 3-tier lifecycle (draft/saved/completed) [ADDED 2025]Orders.tsx- Purchase order management with supplier trackingUsers.tsx- User management with charge code assignments [UPDATED 2025]Settings.tsx- System settings with permission management [UPDATED 2025]Reports.tsx- Report generation, analytics, and payment reconciliation [UPDATED 2025]Backups.tsx- Database backup management (admin only)Documentation.tsx- Embedded documentation viewer
Utility Libraries:
client/src/lib/Shared utility functions and helpers:
roleUtils.ts- Role display names and badge utilities [ADDED 2025]queryClient.ts- React Query configurationutils.ts- General utility functions
Backend Architecture (server/)
Core Server Files
Application Entry Point:
server/index.tsExpress.js server setup with middleware stack, session management, and route registration. Includes health check endpoint and graceful shutdown handling.
API Route Definitions:
server/routes.tsComplete API endpoint definitions with role-based access control. Routes are organized by domain:
Items API: CRUD operations with location/unit fields [UPDATED 2025]
Sales & Quotes API: Draft/saved/completed lifecycle management [UPDATED 2025]
Orders API: Purchase order management
Users API: User management with charge code assignments [UPDATED 2025]
Charge Codes API: Validation and assignment endpoints [ADDED 2025]
Reports API: Analytics with payment reconciliation [UPDATED 2025]
Permissions API: Permission management endpoints [ADDED 2025]
Data Access Layer:
server/storage.tsDatabase operations using Drizzle ORM. Provides abstraction for all database queries with type safety.
Database Configuration:
server/dbConfig.tsPostgreSQL connection setup with connection pooling and error handling.
server/dbInit.tsDatabase initialization and schema verification on startup.
Business Logic Modules
Charge Code Validation: [ADDED 2025]
Validation rules enforced server-side:
Existence Check: Code must exist in
chargecodestableTime Validity:
validFromandvalidUntildate range checksHold Status: Reject codes with
onHold = trueCategory Restrictions: Check
charge_code_exclusionstableUser Authorization: Verify user has access (basic users only see assigned codes)
PIN Protection: Require PIN for high-value codes (if configured)
Sales Lifecycle Management: [UPDATED 2025]
Three-tier quote/sale system:
Draft Quotes (Session-based): - Stored in Redis with 4-hour expiration - Tied to
sessionId- Items not reserved (stock can change) - Can be saved or processed directlySaved Quotes (Persistent): - Stored in
quotestable with statussaved- Named quotes with customer information - Can be edited, duplicated, or processed - No stock reservationCompleted Sales (Immutable): - Stored in
salestable with statuscompleted- Stock immediately deducted - Charge code validated and locked in - Full audit trail viastock_movements-isPaid = false(payment reconciliation comes later)Paid Sales (Reconciled): - Same as completed but
isPaid = true- Indicates accounting reconciliation complete - Marked via Reports page
Sale Processing Transaction:
// Atomic transaction for quote → sale conversion
async function processSale(quoteId: string, chargeCode: string) {
return db.transaction(async (tx) => {
// 1. Validate charge code
await validateChargeCode(chargeCode, items, userId);
// 2. Create sale record
const sale = await tx.insert(sales).values({
chargeCode,
status: 'completed',
isPaid: false,
totalAmount,
});
// 3. Create sale item snapshots (immutable)
await tx.insert(saleItems).values(
items.map(item => ({
saleId: sale.id,
itemId: item.id,
name: item.name, // Snapshot
sku: item.sku, // Snapshot
price: item.price, // Snapshot at time of sale
vatRate: item.vatRate,
location: item.location, // For picking
unit: item.unit, // For quantity interpretation
quantity: item.quantity,
}))
);
// 4. Deduct stock and create audit trail
for (const item of items) {
await tx.update(items)
.set({ currentStock: sql`${items.currentStock} - ${item.quantity}` })
.where(eq(items.id, item.id));
await tx.insert(stockMovements).values({
itemId: item.id,
type: 'out',
quantity: item.quantity,
reason: `Sale ${sale.id}`,
performedBy: userId,
});
}
// 5. Clear draft quote or mark saved quote as processed
if (isDraftQuote) {
await clearDraftQuote(sessionId);
} else {
await tx.update(quotes)
.set({ status: 'processed' })
.where(eq(quotes.id, quoteId));
}
return sale;
});
}
Invoice Parsing:
server/invoiceParser.tsPDF invoice processing for automated data extraction from supplier invoices.
Database Backup:
server/backup.tsAutomated PostgreSQL backup system with compression and retention policies.
DevOps and Testing Infrastructure
CI/CD Pipeline Structure
The application uses GitHub Actions for comprehensive CI/CD automation:
- GitHub Actions Workflow (.github/workflows/main.yml):
Setup Dependencies: Node.js and Docker layer caching
Lint and Type Check: Code quality validation
Unit Tests: Jest testing with PostgreSQL service container
Security Scan: npm audit, Retire.js, and Trivy vulnerability scanning
Docker Build: Multi-stage container building and testing
Performance Tests: k6 load testing (main branch only)
Integration Tests: Full stack testing with Docker Compose
Documentation: Auto-generated docs with test result integration
Performance Testing
- k6 Load Testing (
performance-tests/load-test.js): Health Endpoint Testing: Application availability and response times
Authentication Flow: Login/logout performance validation
API Endpoint Testing: Public API response time validation
Concurrent User Simulation: 20 users with staged load testing
Performance Thresholds: 95th percentile under 500ms, <10% error rate
- Test Execution Environment:
Full Docker Compose stack (app, replit-auth, database, redis)
Service health checks and readiness validation
Performance metrics collection and dashboard integration
Testing Framework
- Jest Test Structure (
server/__tests__/): Unit Tests: Individual component and function testing
Integration Tests: API endpoint and database interaction testing
End-to-End Tests: Complete workflow validation
Coverage Reporting: Automated lcov report generation
- Test Database Configuration:
PostgreSQL 15 Alpine service container for CI/CD
Isolated test database per workflow run
Automatic schema initialization via
init.sqlEnvironment-specific configurations
Docker Infrastructure
- Container Architecture:
Development:
docker-compose.ymlwith hot reload volumesProduction:
docker-compose.prod.ymloptimized for deploymentTesting:
docker-compose.test-prod.ymlfor CI/CD validationMulti-stage Dockerfile: Separate development and production targets
- Service Components:
Main Application: Node.js Express server with React frontend
Authentication Service:
docker/replit-auth/local OIDC providerDatabase: PostgreSQL with automated migrations
Redis: Session storage and caching
pgAdmin: Database administration interface (development)
Documentation System
- Sphinx Documentation (
docs/): ReStructuredText: Primary documentation format
Auto-generated API Docs: TypeScript API reference
Test Result Integration: Coverage reports and test results
CI/CD Dashboard: Interactive navigation interface
GitHub Pages Deployment: Automated documentation publishing
Database Schema and Migrations
Schema Organization
Shared Schema Definition (shared/schema.ts):
The database schema is defined using Drizzle ORM with full TypeScript type safety. All tables are exported with inferred TypeScript types.
Key Tables and Recent Additions:
Core Tables:
users- User accounts with role (user/superuser/admin) [UPDATED 2025]items- Inventory items withlocationandunitfields [UPDATED 2025]categories- Item categorizationsuppliers- Supplier managementchargecodes- Charge codes with validity dates and hold status
Sales and Orders:
quotes- Saved quotes with status (saved/processed) [UPDATED 2025]quote_items- Line items for saved quotessales- Completed sales withisPaidflag [UPDATED 2025]sale_items- Immutable snapshots with location/unit [UPDATED 2025]orders- Purchase ordersorder_items- Purchase order line items
Audit and Tracking:
stock_movements- Complete audit trail for all stock changesnotes- Attachable notes for items, suppliers, orders, charge codes
Permission System [ADDED 2025]:
permissions- System-wide permissions (45 permissions)user_permissions- User-specific permission assignmentscharge_code_assignments- Links users to authorized charge codes [NEW TABLE]
Session Management:
sessions- Express session storage (PostgreSQL Connect)
Critical Field Additions [ADDED 2025]:
// items table
export const items = pgTable('items', {
// ... existing fields
location: varchar('location', { length: 255 }), // Physical storage
unit: varchar('unit', { length: 50 }), // Measurement unit
vatIncluded: boolean('vat_included').default(false), // Price interpretation
});
// sales table
export const sales = pgTable('sales', {
// ... existing fields
isPaid: boolean('is_paid').default(false), // Payment reconciliation
chargeCode: varchar('charge_code', { length: 50 }).notNull(),
});
// sale_items table (snapshots)
export const saleItems = pgTable('sale_items', {
// ... existing fields
location: varchar('location', { length: 255 }), // For picking
unit: varchar('unit', { length: 50 }), // For interpretation
price: decimal('price', { precision: 10, scale: 2 }), // Snapshot
vatRate: decimal('vat_rate', { precision: 5, scale: 2 }), // Snapshot
});
// charge_code_assignments table (NEW)
export const chargeCodeAssignments = pgTable('charge_code_assignments', {
id: serial('id').primaryKey(),
userId: varchar('user_id').notNull().references(() => users.id, { onDelete: 'cascade' }),
chargeCode: varchar('charge_code', { length: 50 }).notNull().references(() => chargeCodes.code, { onDelete: 'cascade' }),
assignedBy: varchar('assigned_by').references(() => users.id),
assignedAt: timestamp('assigned_at').defaultNow(),
notes: text('notes'),
}, (table) => ({
uniqueUserChargeCode: unique('unique_user_charge_code').on(table.userId, table.chargeCode),
}));
Migration System
Migration Files (migrations/):
Sequential SQL migration files with numbering convention:
001_initial_schema.sql- Base tables002_add_categories.sql- Category system…
013_add_charge_code_assignments.sql- Permission system [ADDED 2025]
Migration Execution:
Docker Startup (
init.sql): - Runs on first database initialization - Creates all tables if they don’t exist - Includes latest schema with all fieldsData Migration Script (
data_migration_script.py): - Auto-detects migration files inmigrations/directory - Tracks applied migrations inschema_migrationstable - Applies only new migrations in sequence - Used for upgrading existing databasesManual Migration (
scripts/generate-migration.ts): - Generates new migration files with proper numbering - Includes template for up/down migrations
Migration Dependency Order:
See database-organization for complete migration tier breakdown.
Key Dependencies: - Tier 1: Users, sessions, permissions (no dependencies) - Tier 2: Items, categories, suppliers, charge codes (depend on users) - Tier 3: Charge code assignments (depend on users and charge codes) - Tier 4: Quotes, orders (depend on items, suppliers) - Tier 5: Sales, stock movements (depend on quotes, items)
Authentication Flow
Multi-Modal Authentication System
The system supports both university SSO and local accounts with a unified flow:
1. Route Protection:
// Middleware stack
app.get('/api/protected',
requireAuth, // Verify user is logged in
requireRole(['admin', 'superuser']), // Check role permissions
requirePermission('view_reports'), // Check specific permission
(req, res) => {
// Handle authenticated request
}
);
2. Role-Based Access Control:
export function requireRole(roles: string | string[]) {
return (req: Request, res: Response, next: NextFunction) => {
const user = req.user as any;
const userRole = user?.role;
const allowedRoles = Array.isArray(roles) ? roles : [roles];
if (!allowedRoles.includes(userRole)) {
return res.status(403).json({ message: "Insufficient permissions" });
}
next();
};
}
3. Permission-Based Access Control: [ADDED 2025]
export function requirePermission(permissionName: string) {
return async (req: Request, res: Response, next: NextFunction) => {
const user = req.user as any;
// System admins bypass permission checks
if (user.role === 'admin') {
return next();
}
// Check if user has specific permission
const hasPermission = await db
.select()
.from(userPermissions)
.where(
and(
eq(userPermissions.userId, user.id),
eq(userPermissions.permissionName, permissionName)
)
)
.limit(1);
if (!hasPermission.length) {
return res.status(403).json({
message: "You don't have permission to perform this action"
});
}
next();
};
}
4. Charge Code Authorization: [ADDED 2025]
// Check if user can use a specific charge code
export async function canUseChargeCode(
userId: string,
chargeCode: string
): Promise<boolean> {
const user = await getUserById(userId);
// Managers and admins can use any charge code
if (user.role === 'admin' || user.role === 'superuser') {
return true;
}
// Basic users can only use assigned charge codes
const assignment = await db
.select()
.from(chargeCodeAssignments)
.where(
and(
eq(chargeCodeAssignments.userId, userId),
eq(chargeCodeAssignments.chargeCode, chargeCode)
)
)
.limit(1);
return assignment.length > 0;
}
Three-Tier Permission Model
User (Basic Role):
View inventory (read-only)
Create quotes and sales (with assigned charge codes only)
View own purchase history
Cannot manage users, items, or system settings
Manager (Superuser Role):
All User permissions
Full CRUD on inventory items (with location/unit)
Use any charge code (no restrictions)
Create and manage purchase orders
View all reports and analytics
Assign charge codes to basic users
Cannot manage system users or permissions
System Admin (Admin Role):
All Manager permissions
User management (create, edit, delete, password reset)
Permission assignment and role changes
System configuration and settings
Database backups and recovery
Full system access (bypasses all permission checks)
Role Display Mapping
Frontend Display Names (client/src/lib/roleUtils.ts):
export const ROLE_DISPLAY_NAMES = {
user: 'User', // Basic role
superuser: 'Manager', // Full operations, no user mgmt
admin: 'System Admin' // Full system access
};
This ensures consistent labeling throughout the UI while maintaining database compatibility with existing role values.
Summary
This code structure provides a solid foundation for university-grade inventory management while maintaining developer productivity and code quality. Recent additions in 2025 (permission system, location/unit tracking, charge code validation, and sales lifecycle management) have significantly enhanced the system’s capabilities for enterprise deployment.