Initial commit: Premier Gunner tracker + StartOS 0.4.0 s9pk package
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import { db } from '../db.js';
|
||||
|
||||
const ISO = /^\d{4}-\d{2}-\d{2}$/;
|
||||
|
||||
function ensureDay(day) {
|
||||
db.prepare('INSERT OR IGNORE INTO training_days (day) VALUES (?)').run(day);
|
||||
}
|
||||
|
||||
function dayPayload(day) {
|
||||
const td = db.prepare('SELECT day, notes FROM training_days WHERE day = ?').get(day)
|
||||
|| { day, notes: '' };
|
||||
const entries = db.prepare(
|
||||
'SELECT id, category_id, created_at FROM entries WHERE day = ? ORDER BY id'
|
||||
).all(day);
|
||||
const valuesByEntry = new Map();
|
||||
if (entries.length) {
|
||||
const ids = entries.map((e) => e.id);
|
||||
const rows = db.prepare(
|
||||
`SELECT entry_id, metric_id, value FROM entry_values WHERE entry_id IN (${ids.map(() => '?').join(',')})`
|
||||
).all(...ids);
|
||||
for (const r of rows) {
|
||||
if (!valuesByEntry.has(r.entry_id)) valuesByEntry.set(r.entry_id, []);
|
||||
valuesByEntry.get(r.entry_id).push({ metric_id: r.metric_id, value: r.value });
|
||||
}
|
||||
}
|
||||
const plans = db.prepare(
|
||||
'SELECT category_id, note FROM plans WHERE day = ?'
|
||||
).all(day);
|
||||
return {
|
||||
day: td.day,
|
||||
notes: td.notes,
|
||||
entries: entries.map((e) => ({ ...e, values: valuesByEntry.get(e.id) || [] })),
|
||||
plans,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function entryRoutes(app) {
|
||||
app.get('/api/day/:day', async (req, reply) => {
|
||||
const { day } = req.params;
|
||||
if (!ISO.test(day)) return reply.code(400).send({ error: 'Bad date' });
|
||||
return dayPayload(day);
|
||||
});
|
||||
|
||||
app.post('/api/entries', async (req, reply) => {
|
||||
const { day, category_id, values } = req.body || {};
|
||||
if (!ISO.test(day || '')) return reply.code(400).send({ error: 'Bad date' });
|
||||
const cat = db.prepare('SELECT id FROM categories WHERE id = ?').get(Number(category_id));
|
||||
if (!cat) return reply.code(400).send({ error: 'Unknown category' });
|
||||
|
||||
const tx = db.transaction(() => {
|
||||
ensureDay(day);
|
||||
const { lastInsertRowid: entryId } = db.prepare(
|
||||
'INSERT INTO entries (day, category_id) VALUES (?, ?)'
|
||||
).run(day, cat.id);
|
||||
if (Array.isArray(values)) {
|
||||
const ins = db.prepare('INSERT INTO entry_values (entry_id, metric_id, value) VALUES (?, ?, ?)');
|
||||
for (const v of values) {
|
||||
if (v && v.metric_id != null) ins.run(entryId, Number(v.metric_id), Number(v.value) || 0);
|
||||
}
|
||||
}
|
||||
return entryId;
|
||||
});
|
||||
tx();
|
||||
return dayPayload(day);
|
||||
});
|
||||
|
||||
app.delete('/api/entries/:id', async (req, reply) => {
|
||||
const id = Number(req.params.id);
|
||||
const row = db.prepare('SELECT day FROM entries WHERE id = ?').get(id);
|
||||
db.prepare('DELETE FROM entries WHERE id = ?').run(id);
|
||||
return reply.send(row ? dayPayload(row.day) : { ok: true });
|
||||
});
|
||||
|
||||
app.put('/api/day/:day/notes', async (req, reply) => {
|
||||
const { day } = req.params;
|
||||
if (!ISO.test(day)) return reply.code(400).send({ error: 'Bad date' });
|
||||
const notes = String((req.body && req.body.notes) || '');
|
||||
ensureDay(day);
|
||||
db.prepare('UPDATE training_days SET notes = ? WHERE day = ?').run(notes, day);
|
||||
return { ok: true, notes };
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user