mirror of
https://github.com/screentinker/screentinker.git
synced 2026-05-15 07:32:23 -06:00
Hide unclaimed devices from dashboard, add unassigned API, add upgrade docs
- Filter out devices with no user_id from the main device listing - Add GET /api/devices/unassigned endpoint (admin only) for unclaimed devices - Add "Updating" section to README with upgrade instructions Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
d18045a386
commit
4ae7533b85
34
README.md
34
README.md
|
|
@ -192,6 +192,40 @@ server {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Updating
|
||||||
|
|
||||||
|
To update a running instance to the latest version:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/screentinker
|
||||||
|
|
||||||
|
# Back up the database first
|
||||||
|
sqlite3 server/db/remote_display.db ".backup server/db/backup-$(date +%F).db"
|
||||||
|
|
||||||
|
# Pull latest code
|
||||||
|
git pull origin main
|
||||||
|
|
||||||
|
# Install any new dependencies
|
||||||
|
cd server && npm install --production
|
||||||
|
|
||||||
|
# Restart the service
|
||||||
|
sudo systemctl restart screentinker
|
||||||
|
```
|
||||||
|
|
||||||
|
If you deployed without git, you can initialize it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /opt/screentinker
|
||||||
|
git init
|
||||||
|
git remote add origin https://github.com/screentinker/screentinker.git
|
||||||
|
git fetch origin main
|
||||||
|
git checkout origin/main -- .
|
||||||
|
cd server && npm install --production
|
||||||
|
sudo systemctl restart screentinker
|
||||||
|
```
|
||||||
|
|
||||||
|
Your database, uploads, and configuration are preserved — only code files are updated.
|
||||||
|
|
||||||
### Backups
|
### Backups
|
||||||
|
|
||||||
The SQLite database is at `server/db/remote_display.db`. Back it up regularly:
|
The SQLite database is at `server/db/remote_display.db`. Back it up regularly:
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,27 @@ router.get('/', (req, res) => {
|
||||||
INNER JOIN (SELECT device_id, MAX(captured_at) as max_at FROM screenshots GROUP BY device_id) latest
|
INNER JOIN (SELECT device_id, MAX(captured_at) as max_at FROM screenshots GROUP BY device_id) latest
|
||||||
ON sc.device_id = latest.device_id AND sc.captured_at = latest.max_at
|
ON sc.device_id = latest.device_id AND sc.captured_at = latest.max_at
|
||||||
) s ON d.id = s.device_id
|
) s ON d.id = s.device_id
|
||||||
${isAdmin ? '' : 'WHERE (d.user_id = ? OR d.team_id IN (SELECT team_id FROM team_members WHERE user_id = ?))'}
|
${isAdmin ? 'WHERE d.user_id IS NOT NULL' : 'WHERE d.user_id IS NOT NULL AND (d.user_id = ? OR d.team_id IN (SELECT team_id FROM team_members WHERE user_id = ?))'}
|
||||||
ORDER BY d.created_at ASC
|
ORDER BY d.created_at ASC
|
||||||
LIMIT ? OFFSET ?
|
LIMIT ? OFFSET ?
|
||||||
`).all(...(isAdmin ? [] : [req.user.id, req.user.id]), Math.min(parseInt(req.query.limit) || 100, 500), parseInt(req.query.offset) || 0);
|
`).all(...(isAdmin ? [] : [req.user.id, req.user.id]), Math.min(parseInt(req.query.limit) || 100, 500), parseInt(req.query.offset) || 0);
|
||||||
res.json(devices);
|
res.json(devices);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// List unclaimed provisioning devices (admin only)
|
||||||
|
router.get('/unassigned', (req, res) => {
|
||||||
|
if (!['admin', 'superadmin'].includes(req.user.role)) {
|
||||||
|
return res.status(403).json({ error: 'Admin access required' });
|
||||||
|
}
|
||||||
|
const devices = db.prepare(`
|
||||||
|
SELECT id, pairing_code, status, ip_address, android_version, app_version,
|
||||||
|
screen_width, screen_height, created_at, last_heartbeat
|
||||||
|
FROM devices WHERE user_id IS NULL
|
||||||
|
ORDER BY created_at DESC
|
||||||
|
`).all();
|
||||||
|
res.json(devices);
|
||||||
|
});
|
||||||
|
|
||||||
// Get single device with telemetry history
|
// Get single device with telemetry history
|
||||||
router.get('/:id', (req, res) => {
|
router.get('/:id', (req, res) => {
|
||||||
const device = db.prepare('SELECT d.*, u.email as owner_email, u.name as owner_name FROM devices d LEFT JOIN users u ON d.user_id = u.id WHERE d.id = ?').get(req.params.id);
|
const device = db.prepare('SELECT d.*, u.email as owner_email, u.name as owner_name FROM devices d LEFT JOIN users u ON d.user_id = u.id WHERE d.id = ?').get(req.params.id);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue