A full-stack blockchain-based construction material management system with Flask backend and React frontend. Features role-based access control, real-time inventory tracking, and project management capabilities.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
- Backend: Flask 2.3.3, Flask-SQLAlchemy 3.1.1, SQLite
- Frontend: React 19.1.0, Vite, Tailwind CSS 4.1.11, Material-UI 7.2.0
- Mobile: Capacitor with Android/iOS support
- Authentication: JWT tokens
- Database: SQLite with prefixed ID system
The application uses SQLite with multiple collections organized by functionality:
- User Types: User roles with permissions (admin, worker, client, consultant, pm) and card menu access
- Users: User accounts with authentication, user type assignment, and activity tracking
- Material Types: Types of materials with units (cm, meter, unit, etc.)
- Workflow Types: Predefined workflow templates for processes
- Log Types: Categories for logging activities
- Process State Types: State definitions for projects, work orders, tasks, and subtasks with Chinese translations, colors, and icons
- Item State Types: State definitions for items (available, assigned, used) with Chinese translations and visual styling
- Lots: Material lots from factory with tracking, linked to material types and projects
- Cartons: Sub-containers within lots, containing items
- Items: Individual trackable items with quantity, status, state, location, scan count, and label information
- Stock Logs: Audit trail for stock movements with user, item, lot, and carton references
- Projects: Main project containers with state, dates, priority, and person in charge
- Work Orders: Tasks within projects with workflow types, assignees, estimated hours, and lot assignments
- Tasks: Individual work items with state management and assignees
- Sub Tasks: Detailed task breakdown with state tracking and assignees
- Process Logs: Activity logging for all process entities with user tracking
- Card Menus: Dashboard card definitions with Chinese titles, icons, colors, and routing
- Permissions: Resource-based permission definitions
- User Type Permissions: Many-to-many relationship between user types and permissions
- Permission Audit: Security audit trail for permission checks
- Blockchain Blocks: Immutable blocks containing transactions with hash chaining
- Blockchain Transactions: Item state changes (CREATE, SPLIT, ASSIGN, UPDATE, TRANSFER) with quantity and location tracking
- Blockchain Item States: Current state snapshots of items with transaction references
- Python 3.8+
- Node.js 18+
- npm or yarn
- Android Studio (for mobile development)
- Xcode (for iOS development on macOS)
- Navigate to the backend directory:
cd backend- Create and activate virtual environment:
python -m venv .venv
.venv\Scripts\activate # Windows
# or
source .venv/bin/activate # Linux/Mac- Install dependencies:
pip install -r requirements.txt- Run the application:
python app.pyThe API will be available at http://localhost:5000
- Navigate to the frontend directory:
cd frontend- Install dependencies:
npm install- Start the development server:
npm run devThe frontend will be available at http://localhost:5173
- Add Capacitor to the frontend project (from frontend directory):
npm install @capacitor/core @capacitor/cli
npx cap init "InLINKS" "com.inlinks.inventory" --web-dir=dist- Add mobile platforms:
# For Android
npm install @capacitor/android
npx cap add android
# For iOS (macOS only)
npm install @capacitor/ios
npx cap add ios- Build the frontend:
npm run build- Sync with native platforms:
npx cap sync- Open in IDE:
# Open Android Studio
npx cap open android
# Open Xcode (macOS only)
npx cap open ios- Run on device/emulator:
# Run Android app
npx cap run android
# Run iOS app (macOS only)
npx cap run iosUpdate capacitor.config.json to match your backend URL:
{
"appId": "com.inlinks.inventory",
"appName": "InLINKS",
"webDir": "dist",
"server": {
"cleartext": true,
"allowHttp": true
},
"plugins": {
"SplashScreen": {
"launchShowDuration": 3000,
"launchAutoHide": true
}
}
}- Android: Enable USB debugging on your device and accept the development certificate
- iOS: Use a paid Apple Developer account for device testing
- Hot reload: Use
npm run devfor frontend changes, thennpx cap copyto sync to mobile - API calls: Update API base URL in frontend services to use your machine's IP address for mobile testing
# Build optimized frontend
npm run build
# Copy to native platforms
npx cap copy
# Build release APK (Android)
cd android
./gradlew assembleRelease
# Build release IPA (iOS)
# Use Xcode to archive and distributeInLINKS/
├── backend/ # Flask backend API
│ ├── app.py # Main Flask application
│ ├── models.py # SQLAlchemy models
│ ├── config.py # Configuration settings
│ ├── requirements.txt # Python dependencies
│ ├── routes/ # API route handlers
│ │ ├── common/ # Auth, users, material types
│ │ ├── inventory/ # Lots, cartons, items
│ │ └── process_routes.py # Projects, work orders, tasks
│ └── utils/ # Helper utilities
├── frontend/ # React frontend
│ ├── src/
│ │ ├── App.jsx # Main React application
│ │ ├── pages/ # Page components
│ │ ├── components/ # Reusable UI components
│ │ ├── hooks/ # Custom React hooks
│ │ └── services/ # API service layers
│ ├── capacitor.config.json # Capacitor configuration
│ └── package.json # Node.js dependencies
└── android/ # Generated Android project (after cap add android)
VITE_API_BASE_URL=http://localhost:5000
VITE_APP_TITLE=InLINKS Inventory
{
"appId": "com.inlinks.inventory",
"appName": "InLINKS",
"webDir": "dist",
"server": {
"cleartext": true,
"allowHttp": true,
"hostname": "localhost"
}
}POST /auth/register
Content-Type: application/json
{
"username": "admin",
"password": "admin123",
"user_type_id": "UT001"
}POST /auth/login
Content-Type: application/json
{
"username": "admin",
"password": "admin"
}Returns JWT token to use in subsequent requests:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"user_id": "USR001",
"username": "admin",
"user_type_id": "UT001"
}All protected endpoints require Authorization: Bearer <token> header.
GET /api/user_types- List all user typesPOST /api/user_types- Create new user type
GET /api/users- List all users
GET /api/material_types- List all material typesPOST /api/material_types- Create new material type
{
"material_name": "Cable Cat6",
"material_unit": "meter"
}GET /api/workflow_types- List all workflow typesPOST /api/workflow_types- Create new workflow type
GET /api/lots- List all lotsPOST /api/lots- Create new lot
{
"material_type_id": "MT001",
"factory_lot_number": "LOT2025001"
}GET /api/cartons- List all cartonsPOST /api/cartons- Create new carton
GET /api/items- List all itemsPOST /api/items- Create new item
{
"material_type_id": "MT001",
"quantity": 100.0,
"status": "available"
}GET /api/stock_logs- List all stock logsPOST /api/stock_logs- Create new stock log
GET /api/projects- List all projectsPOST /api/projects- Create new project
{
"project_name": "Office Network Setup",
"person_in_charge_id": "USR001"
}GET /api/work_orders- List all work ordersPOST /api/work_orders- Create new work order
GET /api/tasks- List all tasksPOST /api/tasks- Create new task
GET /api/subtasks- List all subtasksPOST /api/subtasks- Create new subtask
GET /api/dashboardReturns overview statistics and user info.
GET /api/search?q=Cable&type=allSearch across projects, items, and users. Types: all, projects, items, users
POST /api/init_sample_dataPopulates database with sample user types, material types, and workflow types.
All entities use prefixed sequential IDs:
- User Types:
UT001,UT002, ... - Users:
USR001,USR002, ... - Material Types:
MT001,MT002, ... - Workflow Types:
WT001,WT002, ... - Log Types:
LT001,LT002, ... - Process State Types:
PST001,PST002, ... - Item State Types:
IST001,IST002, ... - Lots:
LOT001,LOT002, ... - Cartons:
CTN001,CTN002, ... - Items:
ITM001,ITM002, ... - Stock Logs:
SL001,SL002, ... - Projects:
PRJ001,PRJ002, ... - Work Orders:
WO001,WO002, ... - Tasks:
TSK001,TSK002, ... - Sub Tasks:
SUB001,SUB002, ... - Process Logs:
PL001,PL002, ... - Card Menus:
CM001,CM002, ... - Blockchain Blocks:
BC001,BC002, ... - Blockchain Transactions:
BCT001,BCT002, ... - Blockchain Item States:
BIS001,BIS002, ...
Items use state-based management through ItemStateType entities:
- Available states: Defined in
item_state_typestable with Chinese translations - State tracking: Each item links to
item_state_types.idfor current state - Blockchain integration: All state changes are recorded in blockchain transactions
Projects, Work Orders, Tasks, and SubTasks use process state management:
- State types: Defined in
process_state_typestable for each entity type - Entity-specific states: Separate state definitions for project, workorder, task, subtask
- Visual styling: States include background color, text color, and icon configuration
- Chinese support: All states have Chinese translations
CREATE- New item creationSPLIT- Item quantity divisionASSIGN- Item assignment to tasksUPDATE- Item property updatesTRANSFER- Item location transfers
cd backend
.venv\Scripts\activate # Windows
python app.pycd frontend
npm run dev# Build and sync to mobile
cd frontend
npm run build
npx cap sync
# Run on device/emulator
npx cap run android # or ios- Backend: Edit Python files, Flask will auto-reload
- Frontend: Edit React files, Vite will hot-reload
- Mobile: After frontend changes, run
npm run build && npx cap copy
The SQLite database file inlinks.db will be created automatically in the backend directory when the application starts.
- Port 5000 already in use: Change port in
backend/app.pyor kill existing process - Database locked: Ensure only one Flask instance is running
- Import errors: Check virtual environment is activated and requirements installed
- Port 5173 already in use: Change port in
frontend/vite.config.js - CORS errors: Ensure backend is running and CORS is enabled
- Build failures: Clear
node_modulesand reinstall:rm -rf node_modules && npm install
- API calls failing on mobile: Update API base URL to use your machine's IP address instead of
localhost - Build errors: Ensure Android Studio and Xcode are properly installed
- Sync failures: Run
npx cap sync --forceto force sync
Update your frontend API service to use your machine's IP:
// In frontend/src/services/api.js
const API_BASE_URL = 'http://192.168.1.100:5000'; // Replace with your IPFind your IP address:
# Windows
ipconfig
# macOS/Linux
ifconfig | grep inet- Use connection pooling for database
- Implement caching with Redis
- Add database indexes for frequently queried columns
- Enable code splitting in Vite
- Optimize images and assets
- Use lazy loading for components
- Enable production builds for testing
- Minimize bundle size
- Use native plugins sparingly
- Change the
SECRET_KEYandJWT_SECRET_KEYin production - Use environment variables for sensitive configuration
- Implement proper permission checking based on user types
- Add rate limiting for production use
The API returns appropriate HTTP status codes:
200- Success201- Created400- Bad Request401- Unauthorized404- Not Found500- Internal Server Error







