Initial: Fastify API + DB schema + collab setup

- Fastify API on :3000 (tasks, groups, auth, connectors)
- PostgreSQL schema: users, tasks, task_groups, goals, connectors
- 8 default task groups
- JWT auth (register/login/me)
- API Bridge framework with webhooks
- CLAUDE.md + polling scripts
- Collab worker integration

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude CLI Agent
2026-03-29 09:57:56 +00:00
commit 9d075455e3
13 changed files with 2430 additions and 0 deletions

62
api/src/routes/groups.js Normal file
View File

@@ -0,0 +1,62 @@
// Task Team — Groups CRUD — 2026-03-29
async function groupRoutes(app) {
app.get('/groups', async (req) => {
const { rows } = await app.db.query(
'SELECT * FROM task_groups ORDER BY order_index ASC'
);
return { data: rows };
});
app.get('/groups/:id', async (req) => {
const { rows } = await app.db.query('SELECT * FROM task_groups WHERE id = $1', [req.params.id]);
if (!rows.length) throw { statusCode: 404, message: 'Group not found' };
return { data: rows[0] };
});
app.post('/groups', async (req) => {
const { name, color, icon, order_index, time_zones, user_id } = req.body;
const { rows } = await app.db.query(
'INSERT INTO task_groups (user_id, name, color, icon, order_index, time_zones) VALUES ($1,$2,$3,$4,$5,$6) RETURNING *',
[user_id, name, color, icon || '', order_index || 0, JSON.stringify(time_zones || [])]
);
return { data: rows[0] };
});
app.put('/groups/:id', async (req) => {
const { name, color, icon, order_index, time_zones } = req.body;
const { rows } = await app.db.query(
`UPDATE task_groups SET name=COALESCE($1,name), color=COALESCE($2,color), icon=COALESCE($3,icon),
order_index=COALESCE($4,order_index), time_zones=COALESCE($5,time_zones), updated_at=NOW()
WHERE id=$6 RETURNING *`,
[name, color, icon, order_index, time_zones ? JSON.stringify(time_zones) : null, req.params.id]
);
if (!rows.length) throw { statusCode: 404, message: 'Group not found' };
return { data: rows[0] };
});
app.delete('/groups/:id', async (req) => {
const { rowCount } = await app.db.query('DELETE FROM task_groups WHERE id = $1', [req.params.id]);
if (!rowCount) throw { statusCode: 404, message: 'Group not found' };
return { status: 'deleted' };
});
app.put('/groups/reorder', async (req) => {
const { order } = req.body; // [{id, order_index}]
const client = await app.db.connect();
try {
await client.query('BEGIN');
for (const item of order) {
await client.query('UPDATE task_groups SET order_index=$1, updated_at=NOW() WHERE id=$2', [item.order_index, item.id]);
}
await client.query('COMMIT');
} catch (e) {
await client.query('ROLLBACK');
throw e;
} finally {
client.release();
}
return { status: 'ok' };
});
}
module.exports = groupRoutes;