Some data work and also adding in some new config

This commit is contained in:
2025-08-08 12:58:01 -06:00
parent efaf64e7ab
commit b76906d366
31 changed files with 4027 additions and 21 deletions

View File

@@ -0,0 +1,129 @@
# Admin Panel Implementation Summary
## Overview
Successfully implemented a complete admin panel with start location management feature for the NocoDB Map Viewer application.
## Files Created/Modified
### Backend Changes
- **server.js**:
- Added `SETTINGS_SHEET_ID` parsing
- Updated login endpoint to include admin status
- Updated auth check endpoint to return admin status
- Added `requireAdmin` middleware
- Added admin routes for start location management
- Added public config endpoint for start location
### Frontend Changes
- **map.js**:
- Added `loadStartLocation()` function
- Updated initialization to load start location first
- Updated `displayUserInfo()` to show admin link for admin users
### New Files Created
- **admin.html**: Admin panel interface with interactive map
- **admin.css**: Styling for the admin panel
- **admin.js**: JavaScript functionality for admin panel
### Configuration
- **.env**: Added `NOCODB_SETTINGS_SHEET` environment variable
- **README.md**: Updated with admin panel documentation
## Database Schema
### Settings Table (New)
Required columns for NocoDB Settings table:
- `key` (Single Line Text): Setting identifier
- `title` (Single Line Text): Display name
- `Geo-Location` (Text): Format "latitude;longitude"
- `latitude` (Decimal): Precision 10, Scale 8
- `longitude` (Decimal): Precision 11, Scale 8
- `zoom` (Number): Map zoom level
- `category` (Single Select): "system_setting"
- `updated_by` (Single Line Text): Last updater email
- `updated_at` (DateTime): Last update time
### Login Table (Existing - Updated)
Ensure the existing login table has:
- `Admin` (Checkbox): Admin privileges column
## Features Implemented
### Admin Authentication
- Admin status determined by `Admin` checkbox in login table
- Session-based authentication with admin flag
- Protected admin routes with `requireAdmin` middleware
- Automatic redirect to login for non-admin users
### Start Location Management
- Interactive map interface for setting coordinates
- Manual coordinate input with validation
- "Use Current Map View" button for easy positioning
- Real-time map updates when coordinates change
- Draggable marker for precise positioning
### Data Persistence
- Start location stored in NocoDB Settings table
- Same geographic data format as main locations table
- Automatic creation/update of settings records
- Audit trail with `updated_by` and `updated_at` fields
### Cascading Fallback System
1. **Database** (highest priority): Admin-configured location
2. **Environment** (medium priority): .env file defaults
3. **Hardcoded** (lowest priority): Edmonton coordinates
### User Experience
- All users automatically see admin-configured start location
- Admin users see ⚙️ Admin button in header
- Seamless navigation between main map and admin panel
- Real-time validation and feedback
## API Endpoints
### Admin Endpoints (require admin auth)
- `GET /admin.html` - Serve admin panel page
- `GET /api/admin/start-location` - Get start location with source info
- `POST /api/admin/start-location` - Save new start location
### Public Endpoints
- `GET /api/config/start-location` - Get start location for all users
## Security Features
- Admin-only access to configuration endpoints
- Input validation for coordinates and zoom levels
- Session-based authentication
- CSRF protection through proper HTTP methods
- HTML escaping to prevent XSS
## Next Steps
1. **Setup Database Tables**:
- Create the Settings table in NocoDB with required columns
- Ensure Login table has Admin checkbox column
2. **Configure Environment**:
- Add `NOCODB_SETTINGS_SHEET` URL to .env file
3. **Test Admin Functionality**:
- Login with admin user
- Access `/admin.html`
- Set start location and verify it appears for all users
4. **Future Enhancements** (ready for implementation):
- Additional admin settings (map themes, marker styles, etc.)
- Bulk location management
- User management interface
- System monitoring dashboard
## Benefits Achieved
**Centralized Control**: Admins can change default map view for all users
**Persistent Storage**: Settings survive server restarts and deployments
**User-Friendly Interface**: Interactive map for easy configuration
**Data Consistency**: Uses same format as main location data
**Security**: Proper authentication and authorization
**Scalability**: Easy to extend with additional admin features
**Reliability**: Multiple fallback options ensure map always loads
The implementation provides a robust foundation for administrative control while maintaining the existing user experience and security standards.

View File

@@ -0,0 +1,189 @@
# Cut Feature Implementation Summary
## Overview
Successfully implemented the Cut feature for the map application, allowing admins to create polygon overlays and users to view them on the public map. **Updated:** Fixed Content Security Policy violations by removing all inline event handlers and implementing proper event delegation.
## Database Changes
### New Table: `cuts`
Added cuts table creation to `build-nocodb.sh` with the following columns:
- `id` (Primary Key)
- `name` (Required)
- `description` (Optional)
- `color` (Default: #3388ff)
- `opacity` (Default: 0.3)
- `category` (Custom, Ward, Neighborhood, District)
- `is_public` (Boolean - visible on public map)
- `is_official` (Boolean - marked as official)
- `geojson` (Required - polygon data)
- `bounds` (Calculated bounds for map fitting)
- `created_by`, `created_at`, `updated_at` (Audit fields)
## Backend Implementation
### API Endpoints
- `GET /api/cuts` - Get all cuts (filtered by permissions)
- `GET /api/cuts/public` - Get public cuts for map display
- `GET /api/cuts/:id` - Get single cut
- `POST /api/cuts` - Create cut (admin only)
- `PUT /api/cuts/:id` - Update cut (admin only)
- `DELETE /api/cuts/:id` - Delete cut (admin only)
### Files Created/Modified
-`app/controllers/cutsController.js` - CRUD operations
-`app/routes/cuts.js` - API routes with auth middleware
-`app/routes/index.js` - Added cuts routes
-`app/config/index.js` - Added cuts table ID configuration
-`build-nocodb.sh` - Added cuts table creation
## Frontend Implementation
### Public Map Features
- ✅ Cut selector dropdown in map controls
- ✅ Collapsible legend showing current cut info
- ✅ Single cut display with proper styling
- ✅ Color and opacity from cut properties
### Admin Features
- ✅ Interactive polygon drawing with click-to-add-points
- ✅ Drawing toolbar with finish, undo, clear, cancel buttons
- ✅ Cut properties form with color picker and opacity slider
- ✅ Cut management list with search and filtering
- ✅ Edit, duplicate, delete functionality
- ✅ Import/export cuts as JSON
- ✅ Map preview during editing
### Files Created/Modified
-`app/public/js/cut-drawing.js` - Polygon drawing functionality
-`app/public/js/cut-manager.js` - Cut CRUD and display logic
-`app/public/js/cut-controls.js` - Public map cut controls
-`app/public/js/admin-cuts.js` - Admin cut management
-`app/public/css/modules/cuts.css` - Cut-specific styling
-`app/public/css/style.css` - Added cuts CSS import
-`app/public/index.html` - Added cut controls and legend
-`app/public/admin.html` - Added cuts admin section
-`app/public/js/main.js` - Initialize cut manager and controls
-`app/public/js/map-manager.js` - Added getMap() export
## Key Features Implemented
### Drawing System
- Click-to-add-points polygon creation
- Visual vertex markers with hover effects
- Dynamic polyline connecting vertices
- Minimum 3 points validation
- Undo last point and clear all functionality
- Cancel drawing at any time
### Cut Properties
- Name (required)
- Description (optional)
- Color picker with hex display
- Opacity slider with percentage display
- Category selection (Custom, Ward, Neighborhood, District)
- Public visibility toggle
- Official cut designation
### Management Features
- List all cuts with badges (Public/Private, Official)
- Search cuts by name/description
- Filter by category
- View cut on map with bounds fitting
- Edit existing cuts (populate form from data)
- Duplicate cuts (creates copy with modified name)
- Delete with confirmation
- Export all cuts as JSON
- Import cuts from JSON file with validation
### Public Display
- Dropdown selector with "No overlay" option
- Grouped by category in selector
- Single cut display (replace previous when selecting new)
- Legend showing cut name, color, description
- Collapsible legend with expand/collapse toggle
- Proper styling with cut's color and opacity
## Integration Points
### Authentication & Authorization
- Uses existing auth middleware
- Admin-only creation/editing/deletion
- Public API for map display
- Respects temp user permissions
### Existing Systems
- Integrates with NocoDB service layer
- Uses existing notification system
- Follows established UI patterns
- Works with existing map controls
## Testing Recommendations
1. **Database Setup**
- Run updated `build-nocodb.sh` to create cuts table
- Verify table creation and column types
2. **API Testing**
- Test all CRUD operations
- Verify permission restrictions
- Test public vs admin endpoints
3. **Drawing Functionality**
- Test polygon creation with various point counts
- Test undo/clear/cancel operations
- Verify minimum 3 points validation
4. **Cut Management**
- Test create, edit, duplicate, delete operations
- Test search and filtering
- Test import/export functionality
5. **Map Display**
- Test cut selection and display
- Verify legend updates
- Test bounds fitting
## Future Enhancements
1. **Multiple Cut Display** - Show multiple cuts simultaneously
2. **Cut Statistics** - Calculate area, perimeter
3. **Location Filtering** - Filter locations by selected cut
4. **Cut Sharing** - Share cuts via URL
5. **Advanced Editing** - Edit polygon vertices after creation
6. **Cut Templates** - Pre-defined shapes for quick creation
## Recent Updates - Content Security Policy Compliance
### CSP Violations Fixed (Latest Update)
- **Problem**: Inline event handlers (`onclick`, `onchange`) were violating Content Security Policy
- **Solution**: Replaced all inline handlers with proper event delegation
- **Files Updated**:
- `cut-controls.js` - Completely refactored `populateCutSelector()` function
- `index.html` - Removed inline handlers from mobile overlay modal
- `map-controls.css` - Enhanced dropdown styles and removed auto-show behavior
### Implementation Details
1. **Cut Selector Dropdown**: Now uses event delegation with `data-action` attributes
2. **Mobile Overlay Modal**: Converted to event delegation for all button clicks
3. **Legend Controls**: Updated to use proper event listeners instead of inline handlers
4. **Enhanced User Experience**:
- Dropdown only shows when clicked (removed auto-focus behavior)
- Better mobile responsiveness
- Consistent checkbox-style interface across desktop and mobile
- Proper pointer event handling for smooth interactions
### Technical Improvements
- **Event Delegation**: All click handlers now use `addEventListener` with event delegation
- **Data Attributes**: Using `data-action` and `data-cut-id` for clean event handling
- **DOM Manipulation**: Creating elements programmatically instead of innerHTML with inline handlers
- **CSP Compliance**: Zero inline event handlers remaining in the codebase
## Installation Steps
1. Update database: Run `./build-nocodb.sh` to create cuts table
2. Set environment variable: Add `NOCODB_CUTS_SHEET` if using custom table ID
3. Restart application to load new API routes
4. Access admin panel and navigate to "Map Cuts" section
5. Create test cuts and verify public map display
The Cut feature is now fully implemented, CSP-compliant, and ready for testing!

View File

@@ -0,0 +1,159 @@
# Cut Public View Implementation
## Summary
Successfully implemented multi-cut functionality for the public map view with auto-display of public cuts and multi-select dropdown controls.
## Features Implemented
### 1. Auto-Display Public Cuts
- All cuts marked as public (`is_public = true` or `Public Visibility = true`) are automatically displayed when the map loads
- Uses the existing backend API endpoint `/api/cuts/public`
- Handles different field name variations (normalized data access)
### 2. Multi-Select Dropdown (Desktop)
- Replaces single-cut selector with multi-select checkbox interface
- Shows "Manage map overlays..." with count when cuts are active
- Dropdown shows on focus with:
- Quick action buttons (Show All / Hide All)
- Individual checkboxes for each cut with color indicators
- Official cut badges
- Real-time updates of checkbox states
### 3. Mobile Overlay Modal
- Dedicated mobile interface for cut management
- Accessible via 🗺️ button in mobile sidebar
- Full-screen modal with:
- Show All / Hide All action buttons
- Large touch-friendly checkboxes
- Color indicators and cut names
- Official cut badges
### 4. Legend System
- Dynamic legend showing all active cuts
- Color-coded entries with cut names
- Individual remove buttons (×) for each cut
- Auto-hides when no cuts are displayed
### 5. Multi-Cut Management
- Support for displaying multiple cuts simultaneously
- Individual toggle functionality
- Proper layer management and cleanup
- State persistence across UI interactions
## Files Modified
### HTML (`index.html`)
```html
<!-- Added cut selector container -->
<div class="cut-selector-container">
<select id="cut-selector" class="cut-selector">
<option value="">Select map overlays...</option>
</select>
</div>
<!-- Added mobile overlay button -->
<button id="mobile-overlay-btn" class="btn btn-secondary" title="Map Overlays">
🗺️
</button>
<!-- Added cut legend -->
<div id="cut-legend" class="cut-legend">
<div id="cut-legend-content" class="cut-legend-content"></div>
</div>
<!-- Added mobile overlay modal -->
<div id="mobile-overlay-modal" class="modal hidden">
<!-- Modal content with checkboxes -->
</div>
```
### CSS (`map-controls.css`)
- Multi-select dropdown styles (`.cut-checkbox-container`, `.cut-checkbox-item`)
- Legend styles (`.cut-legend`, `.legend-cut-item`)
- Mobile overlay styles (`.mobile-overlay-list`, `.overlay-actions`)
- Color box indicators (`.cut-color-box`)
- Responsive mobile adjustments
### JavaScript
#### `cut-controls.js` - Enhanced with:
- `autoDisplayAllPublicCuts()` - Auto-display public cuts on load
- `populateCutSelector()` - Multi-select checkbox dropdown
- `updateMultipleCutsUI()` - Update UI for multiple active cuts
- `showMultipleCutsLegend()` - Dynamic legend display
- Global functions: `toggleCutDisplay()`, `showAllCuts()`, `hideAllCuts()`
- Mobile overlay functions: `openMobileOverlayModal()`, `populateMobileOverlayOptions()`
#### `cut-manager.js` - Enhanced with:
- Enhanced `displayCut()` method with multi-cut support
- `isCutDisplayed()` - Check if cut is displayed
- `hideCutById()` - Hide individual cuts by ID
- `hideAllCuts()` - Hide all displayed cuts
- `getDisplayedCuts()` - Get array of currently displayed cuts
- Proper normalization of cut data fields
- Support for auto-displayed tracking
## API Integration
Uses existing backend endpoints:
- `GET /api/cuts/public` - Fetch all public cuts
- Cut data normalization handles various field name formats:
- `id` / `Id` / `ID`
- `name` / `Name`
- `is_public` / `Public Visibility`
- `is_official` / `Official Cut`
- `geojson` / `GeoJSON` / `GeoJSON Data`
## User Experience
### Desktop Workflow:
1. Public cuts auto-display on map load
2. Selector shows "X overlays active" when cuts are displayed
3. Click selector to open checkbox dropdown
4. Use checkboxes to toggle individual cuts on/off
5. Use "Show All" / "Hide All" for quick actions
6. Legend shows active cuts with remove buttons
### Mobile Workflow:
1. Public cuts auto-display on map load
2. Tap 🗺️ button to open overlay modal
3. Use large checkboxes to toggle cuts
4. Use "Show All" / "Hide All" action buttons
5. Close modal to return to map
## Error Handling
- Graceful fallback when API fails (uses mock data for testing)
- Proper error logging for failed cut displays
- Safe handling of missing DOM elements
- Validation of GeoJSON data before display
## Testing Checklist
- [x] Public cuts auto-display on map load
- [x] Multi-select dropdown appears on focus
- [x] Individual cut toggle functionality
- [x] Show All / Hide All quick actions
- [x] Mobile overlay modal functionality
- [x] Legend updates with active cuts
- [x] Color indicators display correctly
- [x] Official cut badges show
- [x] Responsive design works on mobile
- [x] Error handling for missing data
## Performance Considerations
- Efficient layer management using Maps for O(1) lookups
- Minimal DOM manipulation during updates
- Debounced UI updates to prevent excessive redraws
- Memory cleanup when hiding cuts
## Future Enhancements
1. **Cut Categories**: Group cuts by category in dropdown
2. **Search/Filter**: Add search functionality to find specific cuts
3. **Favorites**: Allow users to save favorite cut combinations
4. **Share URLs**: Generate shareable links with specific cuts active
5. **Layer Opacity**: Individual opacity controls per cut
6. **Cut Info**: Expanded cut information in popups/legend

View File

@@ -0,0 +1,85 @@
# Cut System Simplification Summary
## Changes Made
### 1. Moved Color/Opacity Controls to Drawing Toolbar
**Before**: Color and opacity controls were in the form panel, causing complex synchronization issues between form, preview, and drawing layers.
**After**: Color and opacity controls are now directly in the drawing toolbar for immediate visual feedback.
#### HTML Changes:
- Added color picker and opacity slider to `#cut-drawing-toolbar` in `admin.html`
- Removed color/opacity controls from the form panel
- Updated toolbar CSS to support the new controls with mobile responsiveness
#### CSS Changes:
- Enhanced `.cut-drawing-toolbar` styles to accommodate color/opacity controls
- Added `.style-controls` section with proper responsive layout
- Improved mobile responsiveness with column layout for small screens
- Simplified cut polygon CSS rules in `leaflet-custom.css`
### 2. Simplified JavaScript Logic
#### Admin Cuts Manager:
- Added `setupToolbarControls()` method for real-time style updates
- Added `getCurrentColor()` and `getCurrentOpacity()` helper methods
- Updated `handleFormSubmit()` to use toolbar values instead of form values
- Removed complex form-based color/opacity event listeners
- Simplified drawing completion workflow
#### Drawing Integration:
- Color and opacity changes now immediately update the drawing preview
- No more complex synchronization between multiple style update methods
- Direct integration between toolbar controls and drawing layer styles
### 3. User Experience Improvements
**Drawing Workflow**:
1. Click "Start Drawing" to begin
2. Draw polygon by clicking points on map
3. Adjust color and opacity in real-time using toolbar controls
4. See immediate feedback on the polygon as you draw
5. Click "Finish" when satisfied
6. Fill in name, description, and other properties
7. Save the cut
**Benefits**:
- Immediate visual feedback while drawing
- No more disconnect between form values and visual appearance
- Cleaner, more intuitive interface
- Better mobile experience with responsive toolbar
- Simplified code maintenance
## Files Modified
1. **admin.html**: Updated toolbar HTML structure
2. **cuts.css**: Enhanced toolbar styling and mobile responsiveness
3. **leaflet-custom.css**: Simplified cut polygon CSS rules
4. **admin-cuts.js**: Added toolbar controls and simplified style logic
## Testing Checklist
- [ ] Toolbar appears correctly when drawing starts
- [ ] Color picker updates polygon color in real-time
- [ ] Opacity slider updates polygon opacity in real-time
- [ ] Toolbar controls work on mobile devices
- [ ] Form submission uses toolbar values for color/opacity
- [ ] Drawing can be completed and saved successfully
- [ ] Existing cuts still display correctly
- [ ] Public map cut display is unaffected
## Next Steps
1. Test the simplified system thoroughly
2. Remove any remaining complex/unused methods from admin-cuts.js
3. Clean up any console.log debugging statements
4. Consider further UI/UX improvements based on user feedback
## Benefits of Simplification
- **Reduced complexity**: Removed ~200 lines of complex style synchronization code
- **Better UX**: Real-time visual feedback during drawing
- **Easier maintenance**: Clearer separation between drawing controls and form data
- **Mobile friendly**: Responsive toolbar that works well on all screen sizes
- **More intuitive**: Color/opacity controls where users expect them (near the drawing)

View File

@@ -0,0 +1,115 @@
# Temp User Implementation Guide
## Database Schema Changes Required
To implement the temp user type functionality, you need to add the following columns to your NocoDB Login table:
### Required Columns:
1. **UserType** (Single Select)
- Options: "admin", "user", "temp"
- Default: "user"
- Description: Defines the user's permission level
### Optional Columns for Time-Based Expiration:
2. **ExpiresAt** (DateTime, nullable)
- When the account expires (for temp users)
3. **CreatedAt** (DateTime, default: now())
- When the account was created
4. **ExpireDays** (Integer, nullable)
- Number of days until expiration (set by admin)
## Temp User Permissions
### ✅ Allowed Actions:
- Login and view map (if not expired)
- Add new locations
- Edit existing locations
### ❌ Restricted Actions:
- Delete locations
- Access shifts page (/shifts.html)
- Access user profile page (/user.html)
- Access admin panel (/admin.html)
- Search database (only documentation search available)
- Move location markers
- **Login after expiration date** (expired temp users are blocked)
## Expiration Validation
The system now includes comprehensive expiration validation for temp users:
1. **Login Validation**: Expired temp users cannot login
2. **Session Validation**: Expired temp users are automatically logged out
3. **Middleware Checks**: All authenticated routes verify temp user expiration
4. **Frontend Handling**: Expired users receive clear error messages
### Expiration Flow:
1. User attempts login → System checks if temp user is expired → Blocks login if expired
2. Authenticated user makes request → Middleware checks expiration → Logs out if expired
3. Frontend auth check → Detects expiration → Shows message and redirects to login
## Implementation Summary
The implementation adds:
1. **Backend Changes:**
- New middleware functions: `requireNonTemp`, `requireDeletePermission`
- Updated auth controller to handle `userType` in sessions
- **Expiration validation during login** (prevents expired temp users from logging in)
- **Session expiration checks** in all auth middleware
- Protected routes for shifts and user pages
- Updated users controller to support user type and expiration
- Optional account expiration service
2. **Frontend Changes:**
- User type checking in authentication
- **Expiration handling** in auth check with user feedback
- Conditional UI element hiding for temp users
- Restricted search functionality
- Visual indicators (temp badge)
- Updated admin panel for creating temp users
- **Login page expiration message** display
3. **Admin Panel Enhancements:**
- User type selection dropdown (admin/user/temp)
- Expiration days field for temp users
- Enhanced user table with type and expiration display
- Visual indicators for expiring accounts
4. **Database Integration:**
- Session storage of user type
- User type validation during login
- Optional expiration date handling
## Testing Checklist
1. Create test users in NocoDB with different UserType values
2. Test login with each user type
3. **Test that expired temp users cannot login**
4. **Test that expired temp users are logged out during session**
5. Verify temp users cannot access restricted features
6. Test that temp users can add and edit but not delete locations
7. Confirm UI elements are properly hidden for temp users
8. **Verify expiration messages are displayed correctly**
9. **Test admin panel temp user creation with expiration dates**
## Security Notes
- Temp users have limited permissions enforced at both frontend and backend levels
- All restricted routes return 403 errors for temp users
- **Expired temp users are blocked from login and automatically logged out**
- **Expiration validation occurs at multiple checkpoints** (login, middleware, auth check)
- Session includes userType for authorization checks
- Frontend restrictions are backed by server-side validation
- **Clear user feedback for expired accounts** prevents confusion
## Future Enhancements
- Email notifications before account expiration
- Bulk management of temp accounts
- Admin dashboard widgets for temp account monitoring
- Configurable default expiration periods

View File

@@ -0,0 +1,146 @@
# Temp User Implementation Test Guide
## Testing the Implementation
### 1. Database Setup
Before testing, ensure your NocoDB Login table has these columns:
- `UserType` (Single Select: admin, user, temp)
- `ExpiresAt` (DateTime, nullable)
- `CreatedAt` (DateTime)
- `ExpireDays` (Integer, nullable)
### 2. Test User Creation via Admin Panel
1. **Access Admin Panel**
- Login as an admin user
- Navigate to `/admin.html`
- Go to the "Users" section
2. **Create Regular User**
- Email: `testuser@example.com`
- Name: `Test User`
- Password: `password123`
- User Type: `Regular User`
- Click "Create User"
3. **Create Temp User**
- Email: `tempuser@example.com`
- Name: `Temp User`
- Password: `password123`
- User Type: `Temporary User`
- Expires After: `30` days
- Click "Create User"
4. **Create Admin User**
- Email: `adminuser@example.com`
- Name: `Admin User`
- Password: `password123`
- User Type: `Admin`
- Click "Create User"
### 3. Test User Permissions
#### Test Temp User Restrictions:
1. **Login as temp user** (`tempuser@example.com`)
2. **Verify UI Elements Hidden:**
- No "Shifts" link in navigation
- No "Profile" link in navigation
- User email shows "Temp" badge
- Map search only shows "docs" mode (no database search)
3. **Test Location Operations:**
-**Add Location**: Should work
-**Edit Location**: Should work
-**Delete Location**: Delete button should be hidden in edit form
-**Move Location**: Move button should be hidden in popup
4. **Test Restricted Access:**
- Navigate to `/shifts.html` → Should redirect or show 403
- Navigate to `/user.html` → Should redirect or show 403
- Navigate to `/admin.html` → Should redirect or show 403
#### Test Regular User:
1. **Login as regular user** (`testuser@example.com`)
2. **Verify Full Access:**
- ✅ Can access shifts page
- ✅ Can access user profile
- ✅ Can add, edit, and delete locations
- ✅ Can use database search
- ❌ Cannot access admin panel
#### Test Admin User:
1. **Login as admin user** (`adminuser@example.com`)
2. **Verify Admin Access:**
- ✅ Full access to all features
- ✅ Can access admin panel
- ✅ Can create/manage users
### 4. Test Backend API Endpoints
Use browser console or testing tool:
```javascript
// Test temp user cannot delete location
fetch('/api/locations/1', { method: 'DELETE' })
.then(r => r.json())
.then(console.log); // Should return 403 error for temp users
// Test temp user cannot access shifts
fetch('/api/shifts')
.then(r => r.json())
.then(console.log); // Should return 403 error for temp users
```
### 5. Expected Results
#### User Table Display:
- Regular User: Blue "User" badge
- Temp User: Orange "Temp" badge + expiration date
- Admin User: Green "Admin" badge
#### Authentication Response:
```json
{
"authenticated": true,
"user": {
"email": "tempuser@example.com",
"name": "Temp User",
"isAdmin": false,
"userType": "temp"
}
}
```
### 6. Troubleshooting
**If temp user can access restricted features:**
- Check middleware is properly imported in routes
- Verify session includes `userType`
- Check browser console for JavaScript errors
**If user creation fails:**
- Verify NocoDB table has required columns
- Check server logs for database errors
- Ensure column names match exactly
**If UI elements not hiding:**
- Check browser console for auth errors
- Verify `currentUser.userType` is set
- Check CSS classes are applied correctly
### 7. Security Verification
Temp users should receive **403 Forbidden** responses for:
- `DELETE /api/locations/:id`
- `GET /shifts.html`
- `GET /user.html`
- `GET /admin.html`
- `GET /api/shifts`
All restrictions should be enforced server-side, not just hidden in UI.

View File

@@ -0,0 +1,441 @@
# NocoDB Automation Script Development Summary
## Overview
This document summarizes the development of an automated NocoDB table creation script (`build-nocodb.sh`) for the Map Viewer project. The script automates the creation of three required tables: `locations`, `login`, and `settings` with proper schemas and default data.
## Project Requirements
Based on the README.md analysis, the project needed:
- **locations** table: Main map data storage
- **login** table: User authentication
- **settings** table: System configuration and QR codes
- Default admin user and start location records
- Idempotent script (safe to re-run)
## NocoDB API Research
### API Versions
- **v1 API**: `/api/v1/` - Legacy, limited functionality
- **v2 API**: `/api/v2/` - Modern, full-featured (recommended)
### Key API Endpoints Discovered
#### Base/Project Management
```
GET /api/v2/meta/bases # List all bases
POST /api/v2/meta/bases # Create new base
GET /api/v2/meta/bases/{id} # Get base details
```
#### Table Management
```
GET /api/v2/meta/bases/{base_id}/tables # List tables in base
POST /api/v2/meta/bases/{base_id}/tables # Create table
GET /api/v2/meta/bases/{base_id}/tables/{table_id} # Get table details
```
#### Record Management
```
GET /api/v2/tables/{table_id}/records # List records
POST /api/v2/tables/{table_id}/records # Create record
PUT /api/v2/tables/{table_id}/records/{record_id} # Update record
```
### Authentication
All API calls require the `xc-token` header:
```bash
curl -H "xc-token: YOUR_TOKEN" -H "Content-Type: application/json"
```
## Table Schemas Implemented
### 1. Locations Table
Primary table for map data storage:
```json
{
"table_name": "locations",
"columns": [
{"column_name": "id", "uidt": "ID", "pk": true, "ai": true},
{"column_name": "title", "uidt": "SingleLineText"},
{"column_name": "description", "uidt": "LongText"},
{"column_name": "category", "uidt": "SingleSelect", "colOptions": {
"options": [
{"title": "Important", "color": "#ff0000"},
{"title": "Event", "color": "#00ff00"},
{"title": "Business", "color": "#0000ff"},
{"title": "Other", "color": "#ffff00"}
]
}},
{"column_name": "geo_location", "uidt": "LongText"},
{"column_name": "latitude", "uidt": "Decimal"},
{"column_name": "longitude", "uidt": "Decimal"},
{"column_name": "address", "uidt": "LongText"},
{"column_name": "contact_info", "uidt": "LongText"},
{"column_name": "created_at", "uidt": "DateTime"},
{"column_name": "updated_at", "uidt": "DateTime"}
]
}
```
### 2. Login Table
User authentication table:
```json
{
"table_name": "login",
"columns": [
{"column_name": "id", "uidt": "ID", "pk": true, "ai": true},
{"column_name": "username", "uidt": "SingleLineText", "rqd": true},
{"column_name": "email", "uidt": "Email", "rqd": true},
{"column_name": "password", "uidt": "SingleLineText", "rqd": true},
{"column_name": "admin", "uidt": "Checkbox"},
{"column_name": "active", "uidt": "Checkbox"},
{"column_name": "created_at", "uidt": "DateTime"},
{"column_name": "last_login", "uidt": "DateTime"}
]
}
```
### 3. Settings Table
System configuration with QR code support:
```json
{
"table_name": "settings",
"columns": [
{"column_name": "id", "uidt": "ID", "pk": true, "ai": true},
{"column_name": "key", "uidt": "SingleLineText", "rqd": true},
{"column_name": "title", "uidt": "SingleLineText"},
{"column_name": "geo_location", "uidt": "LongText"},
{"column_name": "latitude", "uidt": "Decimal"},
{"column_name": "longitude", "uidt": "Decimal"},
{"column_name": "zoom", "uidt": "Number"},
{"column_name": "category", "uidt": "SingleSelect", "colOptions": {
"options": [
{"title": "system_setting", "color": "#4CAF50"},
{"title": "user_setting", "color": "#2196F3"},
{"title": "app_config", "color": "#FF9800"}
]
}},
{"column_name": "updated_by", "uidt": "SingleLineText"},
{"column_name": "updated_at", "uidt": "DateTime"},
{"column_name": "qr_code_1_url", "uidt": "URL"},
{"column_name": "qr_code_1_label", "uidt": "SingleLineText"},
{"column_name": "qr_code_1_image", "uidt": "Attachment"},
{"column_name": "qr_code_2_url", "uidt": "URL"},
{"column_name": "qr_code_2_label", "uidt": "SingleLineText"},
{"column_name": "qr_code_2_image", "uidt": "Attachment"},
{"column_name": "qr_code_3_url", "uidt": "URL"},
{"column_name": "qr_code_3_label", "uidt": "SingleLineText"},
{"column_name": "qr_code_3_image", "uidt": "Attachment"}
]
}
```
## NocoDB Column Types (UIdt)
Discovered column types and their usage:
- `ID` - Auto-incrementing primary key
- `SingleLineText` - Short text field
- `LongText` - Multi-line text area
- `Email` - Email validation
- `URL` - URL validation
- `Decimal` - Decimal numbers
- `Number` - Integer numbers
- `DateTime` - Date and time
- `Checkbox` - Boolean true/false
- `SingleSelect` - Dropdown with predefined options
- `Attachment` - File upload field
## Script Development Process
### Initial Implementation
1. Created basic structure with environment variable loading
2. Implemented API connectivity testing
3. Added base/project creation functionality
4. Created table creation functions
### Key Challenges Solved
#### 1. Environment Variable Loading
**Issue**: Standard `source .env` wasn't exporting variables
**Solution**: Use `set -a; source .env; set +a` pattern
```bash
set -a # Auto-export all variables
source .env # Load environment file
set +a # Disable auto-export
```
#### 2. API Version Compatibility
**Issue**: Mixed v1/v2 endpoint usage causing errors
**Solution**: Standardized on v2 API with proper URL construction
```bash
BASE_URL=$(echo "$NOCODB_API_URL" | sed 's|/api/v1||')
API_BASE_V2="${BASE_URL}/api/v2"
```
#### 3. Duplicate Table Error
**Issue**: Script failed when tables already existed
**Solution**: Added idempotent table checking
```bash
get_table_id_by_name() {
local base_id=$1
local table_name=$2
# Check if table exists by name
local tables_response
tables_response=$(make_api_call "GET" "/meta/bases/$base_id/tables" "" "Fetching tables")
# Parse JSON to find table ID
local table_id
table_id=$(echo "$tables_response" | grep -o '"id":"[^"]*","table_name":"'"$table_name"'"' | grep -o '"id":"[^"]*"' | head -1 | sed 's/"id":"//;s/"//')
if [ -n "$table_id" ]; then
echo "$table_id"
return 0
else
return 1
fi
}
```
#### 4. JSON Response Parsing
**Issue**: Complex JSON parsing for table IDs
**Solution**: Used grep with regex patterns
```bash
# Extract table ID from JSON response
table_id=$(echo "$response" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
```
## Default Data Records
### Admin User
```json
{
"username": "admin",
"email": "admin@example.com",
"password": "changeme123",
"admin": true,
"active": true,
"created_at": "2025-07-05 12:00:00"
}
```
### Start Location Setting
```json
{
"key": "start_location",
"title": "Map Start Location",
"geo_location": "53.5461;-113.4938",
"latitude": 53.5461,
"longitude": -113.4938,
"zoom": 11,
"category": "system_setting",
"updated_by": "system",
"updated_at": "2025-07-05 12:00:00"
}
```
## Error Handling Patterns
### API Call Wrapper
```bash
make_api_call() {
local method=$1
local endpoint=$2
local data=$3
local description=$4
local api_version=${5:-"v2"}
# Construct full URL
if [[ "$api_version" == "v1" ]]; then
full_url="$API_BASE_V1$endpoint"
else
full_url="$API_BASE_V2$endpoint"
fi
# Make request with timeout
response=$(curl -s -w "%{http_code}" -X "$method" \
-H "xc-token: $NOCODB_API_TOKEN" \
-H "Content-Type: application/json" \
--max-time 30 \
-d "$data" \
"$full_url" 2>/dev/null)
# Parse HTTP code and response
http_code="${response: -3}"
response_body="${response%???}"
# Check for success
if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
echo "$response_body"
return 0
else
print_error "API call failed: $http_code - $response_body"
return 1
fi
}
```
## Final Script Features
### Idempotent Operation
- Checks for existing base/project
- Validates table existence before creation
- Uses existing table IDs when found
- Safe to run multiple times
### Robust Error Handling
- Network timeout protection
- HTTP status code validation
- JSON parsing error handling
- Colored output for status messages
### Environment Integration
- Loads configuration from `.env` file
- Supports custom default coordinates
- Validates required variables
## Usage Instructions
1. **Setup Environment**:
```bash
# Update .env with your NocoDB details
NOCODB_API_URL=https://your-nocodb.com/api/v1
NOCODB_API_TOKEN=your_token_here
```
2. **Run Script**:
```bash
chmod +x build-nocodb.sh
./build-nocodb.sh
```
3. **Post-Setup**:
- Update `.env` with generated table URLs
- Change default admin password
- Verify tables in NocoDB interface
## Lessons Learned
1. **API Documentation**: Always verify API endpoints with actual testing
2. **JSON Parsing**: Shell-based JSON parsing requires careful regex patterns
3. **Idempotency**: Essential for automation scripts in production
4. **Error Handling**: Comprehensive error handling prevents silent failures
5. **Environment Variables**: Proper loading patterns are crucial for script reliability
## Future Enhancements
- Add support for custom table schemas via configuration
- Implement data migration features
- Add backup/restore functionality
- Support for multiple environment configurations
- Integration with CI/CD pipelines
## Script Updates - July 2025
### Column Type Improvements
Updated the build-nocodb.sh script to use proper NocoDB column types based on the official documentation:
#### Locations Table Updates
- **`geo_location`**: Changed from `LongText` to `GeoData` (proper geographic data type)
- **`latitude`**: Added precision (10) and scale (8) for proper decimal handling
- **`longitude`**: Added precision (11) and scale (8) for proper decimal handling
- **`phone`**: Changed from `SingleLineText` to `PhoneNumber` (proper phone validation)
- **`email`**: Using `Email` type for proper email validation
- **Updated field names**: Added proper fields from README.md:
- `first_name`, `last_name` (SingleLineText)
- `unit_number` (SingleLineText)
- `support_level` (SingleSelect with colors: 1=Green, 2=Yellow, 3=Orange, 4=Red)
- `sign` (Checkbox)
- `sign_size` (SingleSelect: Regular, Large, Unsure)
- `notes` (LongText)
- `address` (SingleLineText instead of LongText)
#### Login Table Updates
- **Simplified structure**: Removed username/password fields per README.md specification
- **Core fields**: `email` (Email), `name` (SingleLineText), `admin` (Checkbox)
- **Authentication note**: This is a simplified table - proper authentication should be implemented separately
#### Settings Table Updates
- **`geo_location`**: Changed from `LongText` to `GeoData` for proper geographic data handling
- **`latitude`/`longitude`**: Added precision and scale parameters
- **`value`**: Added missing `value` field from README.md specification
- **QR Code fields**: Simplified to just attachment fields (removed URL/label fields not in README.md)
### Benefits of Proper Column Types
1. **GeoData Type**:
- Proper latitude;longitude format validation
- Better integration with mapping libraries
- Consistent data storage format
2. **PhoneNumber Type**:
- Built-in phone number validation
- Proper formatting and display
- International number support
3. **Email Type**:
- Email format validation
- Prevents invalid email addresses
- Better UI experience
4. **Decimal Precision**:
- Latitude: 10 digits, 8 decimal places (±90.12345678)
- Longitude: 11 digits, 8 decimal places (±180.12345678)
- Provides GPS-level precision for mapping
5. **SingleSelect with Colors**:
- Support Level: Color-coded options for visual feedback
- Sign Size: Consistent option selection
- Category: Organized classification system
### Backward Compatibility
The script maintains backward compatibility while using proper column types. Existing data migration may be needed if upgrading from the old schema.
## Walk Sheet Implementation Overhaul - July 2025
### Overview
The walk sheet system has been completely overhauled to simplify QR code handling and improve mobile usability. The new approach stores only text configuration and generates QR codes on-demand.
### Key Changes Made
#### 1. Database Schema Simplification
- **Removed**: `qr_code_1_image`, `qr_code_2_image`, `qr_code_3_image` attachment fields
- **Kept**: Only text fields for URLs and labels:
- `walk_sheet_title`, `walk_sheet_subtitle`, `walk_sheet_footer`
- `qr_code_1_url`, `qr_code_1_label`
- `qr_code_2_url`, `qr_code_2_label`
- `qr_code_3_url`, `qr_code_3_label`
#### 2. Backend API Updates
- **GET `/api/admin/walk-sheet-config`**: Returns only text configuration
- **POST `/api/admin/walk-sheet-config`**: Saves only text fields
- **Removed**: All QR code upload/storage logic
- **Kept**: Local QR generation via `/api/qr` endpoint for preview/print
#### 3. Frontend Improvements
- **Simplified JavaScript**: Removed `storedQRCodes` logic and image upload handling
- **Better Mobile Support**: Responsive layout with stacked preview on mobile
- **Larger Preview**: Increased from 50% to 75% scale on desktop
- **Real-time Preview**: QR codes generated on-the-fly using canvas
#### 4. CSS Redesign
- **Desktop**: 40/60 split (config/preview) for better preview visibility
- **Mobile**: Stacked layout with horizontal scroll for preview
- **Improved Scaling**: Better touch targets and spacing
- **Professional Styling**: Enhanced typography and visual hierarchy
### Benefits of New Approach
1. **Simpler**: No file storage complexity
2. **Faster**: No upload/download of images
3. **Flexible**: QR codes always reflect current URLs
4. **Cleaner**: Database only stores configuration text
5. **Scalable**: No storage concerns for QR images
6. **Mobile-Friendly**: Better responsive design
### Migration Notes
- Existing QR image data can be ignored (will be regenerated)
- Text configuration will be preserved
- No data loss as QR codes are generated from URLs
- Safe to run build script multiple times
---
*Generated: July 5, 2025*
*Script Version: Column Type Optimized*