📋 What Was Accomplished Backend Changes: - ✅ Enhanced API Endpoint: Updated GET /api/v1/events to accept optional date query parameter - ✅ Input Validation: Added YYYY-MM-DD format validation to PaginationQueryDto - ✅ Database Filtering: Implemented timezone-aware date filtering in EventsService - ✅ Controller Integration: Updated EventsController to pass date parameter to service Frontend Changes: - ✅ Date Picker Component: Created reusable DatePicker component following project design system - ✅ Gallery UI Enhancement: Integrated date picker into gallery page with clear labeling - ✅ State Management: Implemented reactive date state with automatic re-fetching - ✅ Clear Filter Functionality: Added "Clear Filter" button for easy reset - ✅ Enhanced UX: Improved empty states for filtered vs unfiltered views 🔍 Technical Implementation API Design: GET /api/v1/events?date=2025-08-02&limit=20&cursor=xxx Key Files Modified: - meteor-web-backend/src/events/dto/pagination-query.dto.ts - meteor-web-backend/src/events/events.service.ts - meteor-web-backend/src/events/events.controller.ts - meteor-frontend/src/components/ui/date-picker.tsx (new) - meteor-frontend/src/app/gallery/page.tsx - meteor-frontend/src/hooks/use-events.ts - meteor-frontend/src/services/events.ts ✅ All Acceptance Criteria Met 1. ✅ Backend API Enhancement: Accepts optional date parameter 2. ✅ Date Filtering Logic: Returns events for specific calendar date 3. ✅ Date Picker UI: Clean, accessible interface component 4. ✅ Automatic Re-fetching: Immediate data updates on date selection 5. ✅ Filtered Display: Correctly shows only events for selected date 6. ✅ Clear Filter: One-click reset to view all events 🧪 Quality Assurance - ✅ Backend Build: Successful compilation with no errors - ✅ Frontend Build: Successful Next.js build with no warnings - ✅ Linting: All ESLint checks pass - ✅ Functionality: Feature working as specified 🎉 Epic 2 Complete! With Story 2.9 completion, Epic 2: Commercialization & Core User Experience is now DONE! Epic 2 Achievements: - 🔐 Full-stack device status monitoring - 💳 Robust payment and subscription system - 🛡️ Subscription-based access control - 📊 Enhanced data browsing with detail pages - 📅 Date-based event filtering
68 lines
2.3 KiB
JavaScript
68 lines
2.3 KiB
JavaScript
const { Client } = require('pg');
|
|
require('dotenv').config();
|
|
|
|
async function seedInventoryDevices() {
|
|
console.log('=== Seeding Inventory Devices ===');
|
|
|
|
const client = new Client({
|
|
connectionString: process.env.DATABASE_URL,
|
|
ssl: false,
|
|
});
|
|
|
|
try {
|
|
await client.connect();
|
|
|
|
// Sample inventory devices for testing
|
|
const deviceData = [
|
|
{ hardwareId: 'EDGE_DEVICE_001', deviceModel: 'EdgeBox Pro v1.0' },
|
|
{ hardwareId: 'EDGE_DEVICE_002', deviceModel: 'EdgeBox Pro v1.0' },
|
|
{ hardwareId: 'EDGE_DEVICE_003', deviceModel: 'EdgeBox Pro v1.1' },
|
|
{ hardwareId: 'SENSOR_NODE_001', deviceModel: 'SensorNode Lite v2.0' },
|
|
{ hardwareId: 'SENSOR_NODE_002', deviceModel: 'SensorNode Lite v2.0' },
|
|
{ hardwareId: 'GATEWAY_HUB_001', deviceModel: 'GatewayHub Enterprise v1.0' },
|
|
];
|
|
|
|
console.log('📦 Inserting sample inventory devices...');
|
|
|
|
for (const device of deviceData) {
|
|
// Check if device already exists
|
|
const existsResult = await client.query(
|
|
'SELECT id FROM inventory_devices WHERE hardware_id = $1',
|
|
[device.hardwareId]
|
|
);
|
|
|
|
if (existsResult.rows.length === 0) {
|
|
await client.query(
|
|
`INSERT INTO inventory_devices (hardware_id, device_model, is_claimed)
|
|
VALUES ($1, $2, false)`,
|
|
[device.hardwareId, device.deviceModel]
|
|
);
|
|
console.log(` ✅ Added: ${device.hardwareId} (${device.deviceModel})`);
|
|
} else {
|
|
console.log(` ⏭️ Skipped: ${device.hardwareId} (already exists)`);
|
|
}
|
|
}
|
|
|
|
// Show current inventory status
|
|
const inventoryResult = await client.query(`
|
|
SELECT hardware_id, device_model, is_claimed, created_at
|
|
FROM inventory_devices
|
|
ORDER BY created_at DESC
|
|
`);
|
|
|
|
console.log('\n📋 Current Inventory Status:');
|
|
inventoryResult.rows.forEach(row => {
|
|
const status = row.is_claimed ? '🔴 CLAIMED' : '🟢 AVAILABLE';
|
|
console.log(` ${status} ${row.hardware_id} - ${row.device_model || 'No model'}`);
|
|
});
|
|
|
|
console.log(`\n✅ Seeding completed! ${deviceData.length} devices processed.`);
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error seeding inventory devices:', error.message);
|
|
} finally {
|
|
await client.end();
|
|
}
|
|
}
|
|
|
|
seedInventoryDevices(); |