16 KiB
Projects System Implementation - Terra-View
Overview
The Projects system has been successfully scaffolded in Terra-View. This document provides a complete overview of what has been built, how it works, and what needs to be completed.
✅ Completed Components
1. Database Schema
Location: /backend/models.py
Seven new tables have been added:
- ProjectType: Template definitions for project types (Sound, Vibration, Combined)
- Project: Top-level project organization with type reference
- MonitoringLocation: Generic locations (NRLs for sound, monitoring points for vibration)
- UnitAssignment: Links devices to locations
- ScheduledAction: Automated recording control schedules
- RecordingSession: Tracks actual recording/monitoring sessions
- DataFile: File references for downloaded data
Key Features:
- Type-aware design (project_type_id determines features)
- Flexible metadata fields (JSON columns for type-specific data)
- Denormalized fields for efficient queries
- Proper indexing on foreign keys
2. Service Layer
SLMM Client (/backend/services/slmm_client.py)
- Clean wrapper for all SLMM API operations
- Methods for: start/stop/pause/resume recording, get status, configure devices
- Error handling with custom exceptions
- Singleton pattern for easy access
Device Controller (/backend/services/device_controller.py)
- Routes commands to appropriate backend (SLMM for SLMs, SFM for seismographs)
- Unified interface across device types
- Ready for future SFM implementation
Scheduler Service (/backend/services/scheduler.py)
- Background task that checks for pending scheduled actions every 60 seconds
- Executes actions by calling device controller
- Creates/updates recording sessions
- Tracks execution status and errors
- Manual execution support for testing
3. API Routers
Projects Router (/backend/routers/projects.py)
Endpoints:
GET /api/projects/list- Project list with statsGET /api/projects/stats- Overview statisticsPOST /api/projects/create- Create new projectGET /api/projects/{id}- Get project detailsPUT /api/projects/{id}- Update projectDELETE /api/projects/{id}- Archive projectGET /api/projects/{id}/dashboard- Project dashboard dataGET /api/projects/types/list- Get project type templates
Project Locations Router (/backend/routers/project_locations.py)
Endpoints:
GET /api/projects/{id}/locations- List locationsPOST /api/projects/{id}/locations/create- Create locationPUT /api/projects/{id}/locations/{location_id}- Update locationDELETE /api/projects/{id}/locations/{location_id}- Delete locationGET /api/projects/{id}/assignments- List unit assignmentsPOST /api/projects/{id}/locations/{location_id}/assign- Assign unitPOST /api/projects/{id}/assignments/{assignment_id}/unassign- Unassign unitGET /api/projects/{id}/available-units- Get units available for assignment
Scheduler Router (/backend/routers/scheduler.py)
Endpoints:
GET /api/projects/{id}/scheduler/actions- List scheduled actionsPOST /api/projects/{id}/scheduler/actions/create- Create actionPOST /api/projects/{id}/scheduler/schedule-session- Schedule recording sessionPUT /api/projects/{id}/scheduler/actions/{action_id}- Update actionPOST /api/projects/{id}/scheduler/actions/{action_id}/cancel- Cancel actionDELETE /api/projects/{id}/scheduler/actions/{action_id}- Delete actionPOST /api/projects/{id}/scheduler/actions/{action_id}/execute- Manual executionGET /api/projects/{id}/scheduler/status- Scheduler statusPOST /api/projects/{id}/scheduler/execute-pending- Trigger pending executions
4. Frontend
Main Page
Location: /templates/projects/overview.html
Features:
- Summary statistics cards (projects, locations, assignments, sessions)
- Tabbed interface (All, Active, Completed, Archived)
- Project cards grid layout
- Create project modal with two-step flow:
- Select project type (Sound/Vibration/Combined)
- Fill project details
- HTMX-powered dynamic updates
Navigation
Location: /templates/base.html (updated)
- "Projects" link added to sidebar
- Active state highlighting
5. Application Integration
Location: /backend/main.py
- Routers registered
- Page route added (
/projects) - Scheduler service starts on application startup
- Scheduler stops on application shutdown
6. Database Initialization
Script: /backend/init_projects_db.py
- Creates all project tables
- Populates ProjectType with default templates
- ✅ Successfully executed - database is ready
📁 File Organization
terra-view/
├── backend/
│ ├── models.py [✅ Updated]
│ ├── init_projects_db.py [✅ Created]
│ ├── main.py [✅ Updated]
│ ├── routers/
│ │ ├── projects.py [✅ Created]
│ │ ├── project_locations.py [✅ Created]
│ │ └── scheduler.py [✅ Created]
│ └── services/
│ ├── slmm_client.py [✅ Created]
│ ├── device_controller.py [✅ Created]
│ └── scheduler.py [✅ Created]
├── templates/
│ ├── base.html [✅ Updated]
│ ├── projects/
│ │ └── overview.html [✅ Created]
│ └── partials/
│ └── projects/ [📁 Created, empty]
└── data/
└── seismo_fleet.db [✅ Tables created]
🔨 What Still Needs to be Built
1. Frontend Templates (Partials)
Directory: /templates/partials/projects/
Required Files:
project_stats.html
Stats cards for overview page:
- Total/Active/Completed projects
- Total locations
- Assigned units
- Active sessions
project_list.html
Project cards grid:
- Project name, type, status
- Location count, unit count
- Active session indicator
- Link to project dashboard
project_dashboard.html
Main project dashboard panel with tabs:
- Summary stats
- Active locations and assignments
- Upcoming scheduled actions
- Recent sessions
location_list.html
Location cards/table:
- Location name, type, coordinates
- Assigned unit (if any)
- Session count
- Assign/unassign button
assignment_list.html
Unit assignment table:
- Unit ID, device type
- Location name
- Assignment dates
- Status
- Unassign button
scheduler_agenda.html
Calendar/agenda view:
- Scheduled actions sorted by time
- Action type (start/stop/download)
- Location and unit
- Status indicator
- Cancel/execute buttons
2. Project Dashboard Page
Location: /templates/projects/project_dashboard.html
Full project detail page with:
- Header with project name, type, status
- Tab navigation (Dashboard, Scheduler, Locations, Units, Data, Settings)
- Tab content areas
- Modals for adding locations, scheduling sessions
3. Additional UI Components
- Project type selection cards (with icons)
- Location creation modal
- Unit assignment modal
- Schedule session modal (with date/time picker)
- Data file browser
4. SLMM Enhancements
Location: /slmm/app/routers.py (SLMM repo)
New endpoint needed:
POST /api/nl43/{unit_id}/ftp/download
This should:
- Accept destination_path and files list
- Connect to SLM via FTP
- Download specified files
- Save to Terra-View's
data/Projects/directory - Return file list with metadata
5. SFM Client (Future)
Location: /backend/services/sfm_client.py (to be created)
Similar to SLMM client, but for seismographs:
- Get seismograph status
- Start/stop recording
- Download data files
- Integrate with device controller
🚀 Testing the System
1. Start Terra-View
cd /home/serversdown/tmi/terra-view
# Start Terra-View (however you normally start it)
Verify in logs:
Starting scheduler service...
Scheduler service started
2. Navigate to Projects
Open browser: http://localhost:8001/projects
You should see:
- Summary stats cards (all zeros initially)
- Tabs (All Projects, Active, Completed, Archived)
- "New Project" button
3. Create a Project
- Click "New Project"
- Select a project type (e.g., "Sound Monitoring")
- Fill in details:
- Name: "Test Sound Project"
- Client: "Test Client"
- Start Date: Today
- Submit
4. Test API Endpoints
# Get project types
curl http://localhost:8001/api/projects/types/list
# Get projects list
curl http://localhost:8001/api/projects/list
# Get project stats
curl http://localhost:8001/api/projects/stats
5. Test Scheduler Status
curl http://localhost:8001/api/projects/{project_id}/scheduler/status
📋 Dataflow Examples
Creating and Scheduling a Recording Session
- User creates project → Project record in DB
- User adds NRL → MonitoringLocation record
- User assigns SLM to NRL → UnitAssignment record
- User schedules recording → 2 ScheduledAction records (start + stop)
- Scheduler runs every minute → Checks for pending actions
- Start action time arrives → Scheduler calls SLMM via device controller
- SLMM sends TCP command to SLM → Recording starts
- RecordingSession created → Tracks the session
- Stop action time arrives → Scheduler stops recording
- Session updated → stopped_at, duration_seconds filled
- User triggers download → Files copied to
data/Projects/{project_id}/sound/{nrl_name}/ - DataFile records created → Track file references
🎨 UI Design Patterns
Established Patterns (from SLM dashboard):
- Stats Cards: 4-column grid, auto-refresh every 30s
- Sidebar Lists: Searchable, filterable, auto-refresh
- Main Panel: Large central area for details
- Modals: Centered, overlay background
- HTMX: All dynamic updates, minimal JavaScript
- Tailwind: Consistent styling with dark mode support
Color Scheme:
- Primary:
seismo-orange(#f48b1c) - Secondary:
seismo-navy(#142a66) - Accent:
seismo-burgundy(#7d234d)
🔧 Configuration
Environment Variables
SLMM_BASE_URL: SLMM backend URL (default: http://localhost:8100)ENVIRONMENT: "development" or "production"
Scheduler Settings
Located in /backend/services/scheduler.py:
check_interval: 60 seconds (adjust as needed)
📚 Next Steps
Immediate (Get Basic UI Working):
- Create partial templates (stats, lists)
- Test creating projects via UI
- Implement project dashboard page
Short-term (Core Features):
- Add location management UI
- Add unit assignment UI
- Add scheduler UI (agenda view)
Medium-term (Data Flow):
- Implement SLMM download endpoint
- Test full recording workflow
- Add file browser for downloaded data
Long-term (Complete System):
- Implement SFM client for seismographs
- Add data visualization
- Add project reporting
- Add user authentication
🐛 Known Issues / TODOs
- Partial templates missing: Need to create HTML templates for all partials
- SLMM download endpoint: Needs implementation in SLMM backend
- Project dashboard page: Not yet created
- SFM integration: Placeholder only, needs real implementation
- File download tracking: DataFile records not yet created after downloads
- Error handling: Need better user-facing error messages
- Validation: Form validation could be improved
- Testing: No automated tests yet
📖 API Documentation
Project Type Object
{
"id": "sound_monitoring",
"name": "Sound Monitoring",
"description": "...",
"icon": "volume-2",
"supports_sound": true,
"supports_vibration": false
}
Project Object
{
"id": "uuid",
"name": "Project Name",
"description": "...",
"project_type_id": "sound_monitoring",
"status": "active",
"client_name": "Client Inc",
"site_address": "123 Main St",
"site_coordinates": "40.7128,-74.0060",
"start_date": "2024-01-15",
"end_date": null,
"created_at": "2024-01-15T10:00:00",
"updated_at": "2024-01-15T10:00:00"
}
MonitoringLocation Object
{
"id": "uuid",
"project_id": "uuid",
"location_type": "sound",
"name": "NRL-001",
"description": "...",
"coordinates": "40.7128,-74.0060",
"address": "123 Main St",
"location_metadata": "{...}",
"created_at": "2024-01-15T10:00:00"
}
UnitAssignment Object
{
"id": "uuid",
"unit_id": "nl43-001",
"location_id": "uuid",
"project_id": "uuid",
"device_type": "sound_level_meter",
"assigned_at": "2024-01-15T10:00:00",
"assigned_until": null,
"status": "active",
"notes": "..."
}
ScheduledAction Object
{
"id": "uuid",
"project_id": "uuid",
"location_id": "uuid",
"unit_id": "nl43-001",
"action_type": "start",
"device_type": "sound_level_meter",
"scheduled_time": "2024-01-16T08:00:00",
"executed_at": null,
"execution_status": "pending",
"module_response": null,
"error_message": null
}
🎓 Architecture Decisions
Why Project Types?
Allows the system to scale to different monitoring scenarios (air quality, multi-hazard, etc.) without code changes. Just add a new ProjectType record and the UI adapts.
Why Generic MonitoringLocation?
Instead of separate NRL and MonitoringPoint tables, one table with a location_type discriminator keeps the schema clean and allows for combined projects.
Why Denormalized Fields?
Fields like project_id in UnitAssignment (already have via location) enable faster queries without joins.
Why Scheduler in Terra-View?
Terra-View is the orchestration layer. SLMM only handles device communication. Keeping scheduling logic in Terra-View allows for complex workflows across multiple device types.
Why JSON Metadata Columns?
Type-specific fields (like ambient_conditions for sound projects) don't apply to all location types. JSON columns provide flexibility without cluttering the schema.
💡 Tips for Continuing Development
- Follow Existing Patterns: Look at the SLM dashboard code for reference
- Use HTMX Aggressively: Minimize JavaScript, let HTMX handle updates
- Keep Routers Thin: Move business logic to service layer
- Return HTML Partials: Most endpoints should return HTML, not JSON
- Test Incrementally: Build one partial at a time and test in browser
- Check Logs: Scheduler logs execution attempts
- Use Browser DevTools: Network tab shows HTMX requests
📞 Support
For questions or issues:
- Check this document first
- Review existing dashboards (SLM, Seismographs) for patterns
- Check logs for scheduler execution details
- Test API endpoints with curl to isolate issues
✅ Checklist for Completion
- Database schema designed
- Models created
- Migration script run successfully
- Service layer complete (SLMM client, device controller, scheduler)
- API routers created (projects, locations, scheduler)
- Navigation updated
- Main overview page created
- Routes registered in main.py
- Scheduler service integrated
- Partial templates created
- Project dashboard page created
- Location management UI
- Unit assignment UI
- Scheduler UI (agenda view)
- SLMM download endpoint implemented
- Full workflow tested end-to-end
- SFM client implemented (future)
Last Updated: 2026-01-12
Database Status: ✅ Initialized
Backend Status: ✅ Complete
Frontend Status: 🟡 Partial (overview page only)
Ready for Testing: ✅ Yes (basic functionality)