docs: add CLI vs Web functionality comparison
- Document all differences between CLI and web versions - Identify missing features in CLI (email, phone, notes fields) - List database schema mismatches - Provide code changes required to sync CLI with web - Include migration strategy and recommendations
This commit is contained in:
parent
5d66ffa1a6
commit
e789201942
1 changed files with 463 additions and 0 deletions
463
docs/CLI_VS_WEB.md
Normal file
463
docs/CLI_VS_WEB.md
Normal file
|
|
@ -0,0 +1,463 @@
|
|||
# CLI vs Web Functionality Comparison
|
||||
|
||||
## Overview
|
||||
|
||||
This document compares the functionality between the **CLI version** (`minimal_app.py`) and the **Web version** (`app.py`) of the Tablet Management System.
|
||||
|
||||
## Current State
|
||||
|
||||
### Web Version (app.py) - Complete Feature Set
|
||||
|
||||
| Feature | Status | Route | Template |
|
||||
|---------|--------|-------|---------|
|
||||
| Add Tablet | ✅ | `/add_tablet` | `add_tablet.html` |
|
||||
| Add User | ✅ | `/add_user` | `add_user.html` |
|
||||
| Loan Tablet | ✅ | `/loan_tablet` | `loan_tablet.html` |
|
||||
| Return Tablet | ✅ | `/return_tablet/<id>` | N/A (redirects) |
|
||||
| Show Available Tablets | ✅ | `/` (index) | `index.html` |
|
||||
| Show Active Loans | ✅ | `/` (index) | `index.html` |
|
||||
| Loan History | ✅ | `/history` | `history.html` |
|
||||
| User Loans | ✅ | `/user_loans` | `user_loans.html` |
|
||||
| Add Non-Loanable Device | ✅ | `/add_non_loanable_device` | `add_non_loanable_device.html` |
|
||||
| Show Non-Loanable Devices | ✅ | `/non_loanable_devices` | `non_loanable_devices.html` |
|
||||
| Edit Non-Loanable Device | ✅ | `/edit_non_loanable_device/<id>` | `edit_non_loanable_device.html` |
|
||||
| Delete Non-Loanable Device | ✅ | `/delete_non_loanable_device/<id>` | N/A (redirects) |
|
||||
| Project Management | ✅ | `/project_management` | `project_management.html` |
|
||||
|
||||
### CLI Version (minimal_app.py) - Incomplete
|
||||
|
||||
| Feature | Status | Function |
|
||||
|---------|--------|----------|
|
||||
| Add Tablet | ✅ | `add_tablet()` |
|
||||
| Add User | ⚠️ Partial | `add_user()` - Missing email/phone |
|
||||
| Loan Tablet | ✅ | `loan_tablet()` |
|
||||
| Return Tablet | ✅ | `return_tablet()` |
|
||||
| Show Available Tablets | ✅ | `show_available_tablets()` |
|
||||
| Show Active Loans | ✅ | `show_active_loans()` |
|
||||
| Loan History | ✅ | `show_loan_history()` |
|
||||
| Add Non-Loanable Device | ✅ | `add_non_loanable_device()` |
|
||||
| Show Non-Loanable Devices | ✅ | `show_non_loanable_devices()` |
|
||||
| Delete Non-Loanable Device | ✅ | `delete_non_loanable_device()` |
|
||||
| Show Users | ✅ | `show_users()` |
|
||||
| **User Loans** | ❌ Missing | N/A |
|
||||
| **Edit Non-Loanable Device** | ❌ Missing | N/A |
|
||||
| **Project Management** | ❌ Missing | N/A |
|
||||
|
||||
## Missing Features in CLI
|
||||
|
||||
### 1. User Management
|
||||
**Web:** Supports name, email, phone, identification
|
||||
**CLI:** Only supports name, identification
|
||||
|
||||
**Missing:**
|
||||
- Email field
|
||||
- Phone field
|
||||
|
||||
### 2. Tablet Management
|
||||
**Web:** Supports brand, model, serial_number, notes
|
||||
**CLI:** Supports brand, model, serial_number
|
||||
|
||||
**Missing:**
|
||||
- Notes field
|
||||
|
||||
### 3. Non-Loanable Devices
|
||||
**Web:** Full CRUD (Create, Read, Update, Delete)
|
||||
**CLI:** Only Create, Read, Delete
|
||||
|
||||
**Missing:**
|
||||
- Edit functionality
|
||||
|
||||
### 4. Additional Features
|
||||
**Web:** Has these features
|
||||
**CLI:** Missing
|
||||
|
||||
- User Loans page (shows loans by user with search)
|
||||
- Project Management (markdown notes editor)
|
||||
- Flash messages (CLI uses print, which is fine)
|
||||
|
||||
## Database Schema Comparison
|
||||
|
||||
### Web Version Schema (app.py)
|
||||
|
||||
```sql
|
||||
-- tablets
|
||||
CREATE TABLE tablets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT
|
||||
)
|
||||
|
||||
-- users
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
identification TEXT UNIQUE
|
||||
)
|
||||
|
||||
-- loans
|
||||
CREATE TABLE loans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
tablet_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
loan_date TEXT NOT NULL,
|
||||
return_date TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
FOREIGN KEY (tablet_id) REFERENCES tablets (id),
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)
|
||||
|
||||
-- non_loanable_devices
|
||||
CREATE TABLE non_loanable_devices (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
device_type TEXT NOT NULL,
|
||||
location TEXT,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT,
|
||||
purchase_date TEXT,
|
||||
purchase_cost REAL
|
||||
)
|
||||
```
|
||||
|
||||
### CLI Version Schema (minimal_app.py)
|
||||
|
||||
```sql
|
||||
-- tablets
|
||||
CREATE TABLE tablets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'available'
|
||||
-- MISSING: notes TEXT
|
||||
)
|
||||
|
||||
-- users
|
||||
CREATE TABLE users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
identification TEXT UNIQUE
|
||||
-- MISSING: email TEXT, phone TEXT
|
||||
)
|
||||
|
||||
-- loans
|
||||
CREATE TABLE loans (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
tablet_id INTEGER NOT NULL,
|
||||
user_id INTEGER NOT NULL,
|
||||
loan_date TEXT NOT NULL,
|
||||
return_date TEXT,
|
||||
status TEXT DEFAULT 'active',
|
||||
FOREIGN KEY (tablet_id) REFERENCES tablets (id),
|
||||
FOREIGN KEY (user_id) REFERENCES users (id)
|
||||
)
|
||||
|
||||
-- non_loanable_devices
|
||||
CREATE TABLE non_loanable_devices (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
device_type TEXT NOT NULL,
|
||||
location TEXT,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT,
|
||||
purchase_date TEXT,
|
||||
purchase_cost REAL
|
||||
)
|
||||
```
|
||||
|
||||
**Schema Differences:**
|
||||
- `tablets` table: CLI missing `notes` column
|
||||
- `users` table: CLI missing `email` and `phone` columns
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Option 1: Update CLI to Match Web (Recommended)
|
||||
|
||||
Update `minimal_app.py` to:
|
||||
1. Add `notes` field to tablets
|
||||
2. Add `email` and `phone` fields to users
|
||||
3. Add edit functionality for non-loanable devices
|
||||
4. Add user loans view
|
||||
5. Add project management (optional)
|
||||
|
||||
**Pros:**
|
||||
- CLI has full feature parity with web
|
||||
- Same database schema
|
||||
- Users can use either interface
|
||||
|
||||
**Cons:**
|
||||
- More complex CLI
|
||||
- May not be needed if web is primary interface
|
||||
|
||||
### Option 2: Keep CLI Minimal (Current State)
|
||||
|
||||
Leave CLI as-is for basic operations only.
|
||||
|
||||
**Pros:**
|
||||
- Simple, focused CLI
|
||||
- Less code to maintain
|
||||
|
||||
**Cons:**
|
||||
- Database schema mismatch
|
||||
- Users can't access all features via CLI
|
||||
- Confusing for users who expect same functionality
|
||||
|
||||
### Option 3: Create Separate Database (Not Recommended)
|
||||
|
||||
Use different databases for CLI and web.
|
||||
|
||||
**Pros:**
|
||||
- Each can have optimized schema
|
||||
|
||||
**Cons:**
|
||||
- Data duplication
|
||||
- Sync issues
|
||||
- Confusing for users
|
||||
|
||||
## Suggested Action Plan
|
||||
|
||||
### Priority 1: Fix Database Schema Mismatch
|
||||
|
||||
The CLI's `init_db()` creates tables without `notes`, `email`, and `phone` columns, but the web version expects them. This can cause issues.
|
||||
|
||||
**Solution:** Update `minimal_app.py` `init_db()` to match `app.py` schema.
|
||||
|
||||
### Priority 2: Add Missing Fields to CLI Functions
|
||||
|
||||
1. Update `add_tablet()` to accept and store `notes`
|
||||
2. Update `add_user()` to accept and store `email` and `phone`
|
||||
3. Update `show_available_tablets()` and `show_non_loanable_devices()` to display all fields
|
||||
|
||||
### Priority 3: Add Missing Features (Optional)
|
||||
|
||||
1. Add `edit_non_loanable_device()` function
|
||||
2. Add `show_user_loans()` function
|
||||
3. Consider adding project management (lower priority)
|
||||
|
||||
## Code Changes Required
|
||||
|
||||
### 1. Update init_db() in minimal_app.py
|
||||
|
||||
```python
|
||||
def init_db():
|
||||
"""Initialize database with required tables - MATCH WEB VERSION"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Create tablets table - ADD NOTES COLUMN
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS tablets (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
brand TEXT NOT NULL,
|
||||
model TEXT NOT NULL,
|
||||
serial_number TEXT UNIQUE NOT NULL,
|
||||
status TEXT DEFAULT 'available',
|
||||
notes TEXT
|
||||
)
|
||||
''')
|
||||
|
||||
# Create users table - ADD EMAIL AND PHONE COLUMNS
|
||||
cursor.execute('''
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
email TEXT,
|
||||
phone TEXT,
|
||||
identification TEXT UNIQUE
|
||||
)
|
||||
''')
|
||||
|
||||
# loans and non_loanable_devices are already correct
|
||||
# ... rest of init_db
|
||||
```
|
||||
|
||||
### 2. Update add_tablet() Function
|
||||
|
||||
```python
|
||||
def add_tablet(brand, model, serial_number, notes=''):
|
||||
"""Add a new tablet to inventory"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute('''
|
||||
INSERT INTO tablets (brand, model, serial_number, status, notes)
|
||||
VALUES (?, ?, ?, 'available', ?)
|
||||
''', (brand, model, serial_number, notes))
|
||||
conn.commit()
|
||||
print(f"✓ Added tablet: {brand} {model} ({serial_number})")
|
||||
if notes:
|
||||
print(f" Notes: {notes}")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"✗ Error: Serial number {serial_number} already exists")
|
||||
finally:
|
||||
conn.close()
|
||||
```
|
||||
|
||||
### 3. Update add_user() Function
|
||||
|
||||
```python
|
||||
def add_user(name, identification, email='', phone=''):
|
||||
"""Add a new user"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
try:
|
||||
cursor.execute('''
|
||||
INSERT INTO users (name, email, phone, identification)
|
||||
VALUES (?, ?, ?, ?)
|
||||
''', (name, email, phone, identification))
|
||||
conn.commit()
|
||||
print(f"✓ Added user: {name} ({identification})")
|
||||
if email:
|
||||
print(f" Email: {email}")
|
||||
if phone:
|
||||
print(f" Phone: {phone}")
|
||||
except sqlite3.IntegrityError:
|
||||
print(f"✗ Error: Identification {identification} already exists")
|
||||
finally:
|
||||
conn.close()
|
||||
```
|
||||
|
||||
### 4. Update show_available_tablets() to Display Notes
|
||||
|
||||
```python
|
||||
def show_available_tablets():
|
||||
"""Show available tablets"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
cursor.execute("SELECT id, brand, model, serial_number, notes FROM tablets WHERE status = 'available'")
|
||||
tablets = cursor.fetchall()
|
||||
|
||||
print("\n=== Available Tablets ===")
|
||||
if tablets:
|
||||
for tablet in tablets:
|
||||
notes = f" | Notes: {tablet[4]}" if tablet[4] else ""
|
||||
print(f"ID: {tablet[0]}, {tablet[1]} {tablet[2]} ({tablet[3]}){notes}")
|
||||
else:
|
||||
print("No available tablets")
|
||||
|
||||
conn.close()
|
||||
```
|
||||
|
||||
### 5. Add Missing Functions
|
||||
|
||||
#### Edit Non-Loanable Device
|
||||
|
||||
```python
|
||||
def edit_non_loanable_device(device_id, **kwargs):
|
||||
"""Edit a non-loanable device"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Build update query dynamically
|
||||
updates = []
|
||||
params = []
|
||||
for key, value in kwargs.items():
|
||||
if value is not None:
|
||||
updates.append(f"{key} = ?")
|
||||
params.append(value)
|
||||
|
||||
if not updates:
|
||||
print("✗ No fields to update")
|
||||
conn.close()
|
||||
return
|
||||
|
||||
params.append(device_id)
|
||||
query = f"UPDATE non_loanable_devices SET {', '.join(updates)} WHERE id = ?"
|
||||
|
||||
cursor.execute(query, params)
|
||||
conn.commit()
|
||||
|
||||
if cursor.rowcount > 0:
|
||||
print(f"✓ Non-loanable device {device_id} updated")
|
||||
else:
|
||||
print(f"✗ Error: Device {device_id} not found")
|
||||
|
||||
conn.close()
|
||||
```
|
||||
|
||||
#### Show User Loans
|
||||
|
||||
```python
|
||||
def show_user_loans():
|
||||
"""Show loans grouped by user"""
|
||||
conn = sqlite3.connect('tablets.db')
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Get all users with their loans
|
||||
cursor.execute('''
|
||||
SELECT u.id, u.name, u.identification,
|
||||
GROUP_CONCAT(l.id, ",") as loan_ids,
|
||||
COUNT(l.id) as loan_count
|
||||
FROM users u
|
||||
LEFT JOIN loans l ON u.id = l.user_id
|
||||
GROUP BY u.id, u.name, u.identification
|
||||
''')
|
||||
users = cursor.fetchall()
|
||||
|
||||
print("\n=== User Loans ===")
|
||||
if users:
|
||||
for user in users:
|
||||
print(f"\nUser: {user[1]} ({user[2]}) - {user[3]} loans")
|
||||
|
||||
# Get loans for this user
|
||||
cursor.execute('''
|
||||
SELECT l.id, t.brand, t.model, t.serial_number, l.loan_date, l.return_date, l.status
|
||||
FROM loans l
|
||||
JOIN tablets t ON l.tablet_id = t.id
|
||||
WHERE l.user_id = ?
|
||||
ORDER BY l.loan_date DESC
|
||||
''', (user[0],))
|
||||
loans = cursor.fetchall()
|
||||
|
||||
for loan in loans:
|
||||
return_date = loan[5] or 'Not returned'
|
||||
print(f" Loan {loan[0]}: {loan[1]} {loan[2]} ({loan[3]})")
|
||||
print(f" Loan Date: {loan[4]}, Return Date: {return_date}, Status: {loan[6]}")
|
||||
else:
|
||||
print("No users found")
|
||||
|
||||
conn.close()
|
||||
```
|
||||
|
||||
## Migration Strategy
|
||||
|
||||
If you want to update the CLI to match the web version:
|
||||
|
||||
1. **Backup current database**
|
||||
```bash
|
||||
cp tablets.db tablets.db.backup
|
||||
```
|
||||
|
||||
2. **Update minimal_app.py** with the changes above
|
||||
|
||||
3. **Run updated CLI**
|
||||
```bash
|
||||
python3 minimal_app.py
|
||||
```
|
||||
|
||||
4. **Test all functionality**
|
||||
|
||||
5. **If database schema changed**, you may need to:
|
||||
- Drop and recreate tables (if starting fresh)
|
||||
- Or add missing columns with ALTER TABLE (if preserving data)
|
||||
|
||||
## Conclusion
|
||||
|
||||
The CLI version is **lagging behind** the web version in terms of:
|
||||
- Database schema (missing columns)
|
||||
- Feature completeness (missing functions)
|
||||
- Field support (missing email, phone, notes)
|
||||
|
||||
**Recommendation:** Update the CLI to match the web version's database schema and functionality to ensure consistency and avoid confusion for users who may use both interfaces.
|
||||
Loading…
Add table
Add a link
Reference in a new issue