Build a complete asset management system with QR labeling, assignment tracking, depreciation calculation, and maintenance scheduling
* Preview is for reference only. Actual results may vary depending on the AI model, variable values, and tools used.
You are a senior full-stack developer specializing in internal operations systems for Malaysian SMEs. Build a complete Office Asset & Equipment Tracker for {{company_name}} to replace their existing Excel-based asset management.
## Project Context
Malaysian SMEs typically own hundreds of assets — laptops, office furniture, vehicles, machinery — but track them in spreadsheets, leading to lost assets, miscalculated depreciation, and forgotten maintenance. This system solves these core pain points.
## Tech Stack
- **Framework**: Next.js 14 (App Router) + TypeScript
- **Styling**: Tailwind CSS + shadcn/ui component library
- **Database**: Supabase (PostgreSQL + Row Level Security)
- **QR Codes**: qrcode.react for generation, react-qr-reader for scanning
- **Charts**: Recharts (depreciation trend charts)
- **CSV Import**: papaparse
- **Deployment**: Vercel
## Database Schema
Create the following tables with all columns, indexes, and foreign keys:
**asset_categories**
- id (uuid, primary key)
- name (text, not null) — e.g. IT Equipment, Office Furniture, Vehicles
- default_useful_life_years (integer)
- default_depreciation_rate (numeric) — percentage
- created_at (timestamptz)
**locations**
- id (uuid, primary key)
- name (text, not null) — e.g. HQ Floor 3, Penang Branch
- address (text)
- is_active (boolean, default true)
**employees**
- id (uuid, primary key)
- full_name (text, not null)
- department (text)
- email (text)
- employee_code (text, unique)
- is_active (boolean, default true)
**assets** (core table)
- id (uuid, primary key)
- asset_tag (text, unique, not null) — format: AST-YYYY-NNNN
- name (text, not null)
- description (text)
- category_id (uuid, FK → asset_categories)
- serial_number (text)
- brand (text)
- model (text)
- purchase_date (date)
- purchase_price (numeric) — Malaysian Ringgit RM
- useful_life_years (integer)
- salvage_value (numeric)
- current_value (numeric) — auto-calculated book value
- status (text) — enum: in_use / available / under_repair / disposed
- location_id (uuid, FK → locations)
- assigned_to (uuid, FK → employees)
- photo_url (text) — Supabase Storage
- qr_code_data (text) — asset detail page URL
- warranty_expiry (date)
- notes (text)
- created_at (timestamptz)
- updated_at (timestamptz)
Indexes: category_id, location_id, assigned_to, status, asset_tag
**asset_assignments** (check-out / check-in log)
- id (uuid, primary key)
- asset_id (uuid, FK → assets)
- employee_id (uuid, FK → employees)
- assigned_date (date, not null)
- returned_date (date) — null means still in use
- condition_on_assign (text) — Good / Fair / Poor
- condition_on_return (text)
- assigned_by (text) — name of staff who processed the assignment
- notes (text)
Indexes: asset_id, employee_id
**asset_maintenance** (service and repair records)
- id (uuid, primary key)
- asset_id (uuid, FK → assets)
- maintenance_type (text) — Scheduled Service / Breakdown Repair / Preventive Check
- description (text)
- scheduled_date (date)
- completed_date (date)
- cost (numeric) — RM
- vendor (text)
- performed_by (text)
- next_scheduled_date (date)
- status (text) — enum: scheduled / completed / overdue
- notes (text)
Indexes: asset_id, scheduled_date, status
**disposal_records** (write-off and disposal log)
- id (uuid, primary key)
- asset_id (uuid, FK → assets)
- disposal_date (date)
- disposal_method (text) — Sold / Scrapped / Donated / Lost
- disposal_price (numeric) — RM (if sold)
- approved_by (text)
- reason (text)
- created_at (timestamptz)
For all tables: enable RLS. Public read for reference tables (categories, locations, employees). All writes require authenticated session. Wrap auth.uid() in (select auth.uid()) for performance.
## Core Features
### 1. Asset Registry
- Full asset detail form with photo upload to Supabase Storage
- Auto-generate asset tag on creation: AST-{{current year}}-{{4-digit sequence}}
- Asset categories: {{asset_categories}}
- Bulk CSV import with template download (validate required fields, return row-level errors)
- Status management: In Use / Available / Under Repair / Disposed
### 2. QR Code Label System
- Auto-generate a unique QR code for every asset on creation
- QR content = asset detail page URL (e.g. /assets/AST-2024-0042)
- Print-ready label layout: 57×32mm, optimized for label printers
- Batch print selected assets' QR labels from the list view
- Mobile camera QR scanning for instant asset lookup
### 3. Assignment Tracking (Check-Out / Check-In)
- Check-out flow: Select asset → Select employee → Record condition → Confirm
- Check-in flow: Scan or search asset → Record return condition → Update status
- Full assignment history timeline per asset
- View all assets currently held by a specific employee
- Condition comparison: note any damage between check-out and check-in
### 4. Depreciation Calculation (Malaysian Tax Rules)
- Method: {{depreciation_method}} (Straight-Line)
- Formula: Annual Depreciation = (Purchase Price − Salvage Value) / Useful Life Years
- System recalculates current book value monthly
- Depreciation schedule table: yearly depreciation and closing book value
- Depreciation trend line chart using Recharts
- Export depreciation report as CSV for accounting department
- Reference LHDN (Malaysia Inland Revenue) capital allowance guidelines in comments
### 5. Maintenance Scheduling
- Set recurring maintenance schedules per asset (e.g. every 6 months)
- Calendar view (month layout) with upcoming maintenance tasks
- Overdue maintenance highlighted in red with alert badge
- Log completed maintenance: date, cost (RM), vendor name
- Auto-calculate next service date after completion
- Maintenance cost summary report by asset and by category
### 6. Asset Disposal and Write-Off
- Disposal form: reason, method (Sold / Scrapped / Donated / Lost), disposal price
- Record approver name (paper-trail without mandatory e-approval)
- On disposal: set status to "disposed", remove from active asset lists
- Auto-calculate disposal gain/loss: Disposal Price − Current Book Value
### 7. Multi-Location Management
- Assign assets to office locations: {{locations}}
- Filter asset list by location
- Record location transfers with date and reason
- Location summary: asset count and total value per location
## UI/UX Requirements
**Dashboard**
- Top KPI cards: Total Assets, In Use, Available, Under Repair, Total Asset Value (RM)
- Asset breakdown donut chart by category
- Bar chart: asset count per location
- Upcoming maintenance calendar (next 30 days)
- Depreciation overview: estimated depreciation for current financial year
**Asset List Page**
- Toggle between table view and card grid view
- Search: asset tag, name, serial number, assigned employee
- Filters: category, location, status, purchase year
- Sort: name, purchase date, current value
- Table columns: Asset Tag, Name, Category badge, Assigned To, Location, Current Value (RM), Status badge
- Status badge colors: In Use (blue), Available (green), Under Repair (amber), Disposed (gray)
**Asset Detail Page**
- Left panel: asset photo + QR code + Print Label button
- Right panel: full asset info, current status, Check Out / Check In action buttons
- Tab navigation: Details / Depreciation / Assignment History / Maintenance
- Depreciation tab: schedule table + trend line chart
- Assignment History tab: vertical timeline, each entry shows employee name, dates, condition notes
**Navigation**
- Dark nav bar (#0F172A) + yellow (#FCD34D) accent
- Main menu: Dashboard / Assets / Assignments / Maintenance / Reports / Settings
- Top-right: QR Scan quick-access button
- Responsive: hamburger menu on mobile
## Business Rules
- Asset tags are unique and immutable after creation
- Disposed assets cannot be assigned or edited
- Assets with status "under_repair" cannot be assigned to employees
- Only one active assignee per asset at any time
- Depreciation starts from the first day of the month following purchase date
- CSV import must validate all required fields; return a downloadable error report for invalid rows
- All monetary values display in Malaysian Ringgit (RM) with 2 decimal places
- Maintenance status auto-updates to "overdue" when scheduled_date has passed and completed_date is null
## Deliverables
Provide complete, runnable code including:
1. Full SQL migration file with RLS policies and indexes
2. All Next.js pages and components
3. Supabase client utilities (browser, server, admin)
4. QR code generation and print layout logic
5. CSV import parsing with validation (papaparse)
6. Depreciation calculation utility functions
7. Complete package.json with all dependencies
Write all code and comments in English. Use English for all UI labels and text.