From bc73820f6cae0b077c902a4a3a35fbabc1b8280f Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Wed, 8 Apr 2026 14:55:21 +0530 Subject: [PATCH] test: add tags CRUD route to test custom bot_name=code-bot Adds a tags endpoint wired into app.js, with a workflow that sets bot_name to 'code-bot'. The review comment HTML marker should use instead of the default dr-concretio marker. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ai-review-custom-bot.yml | 20 ++++++++ app.js | 2 + routes/tags.js | 53 ++++++++++++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 .github/workflows/ai-review-custom-bot.yml create mode 100644 routes/tags.js diff --git a/.github/workflows/ai-review-custom-bot.yml b/.github/workflows/ai-review-custom-bot.yml new file mode 100644 index 0000000..53d4317 --- /dev/null +++ b/.github/workflows/ai-review-custom-bot.yml @@ -0,0 +1,20 @@ +name: AI Code Review (CodeBot) +on: + pull_request: + types: [opened, synchronize, reopened] + +jobs: + review: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: write + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - uses: concretios/ai-pr-reviewer@v1 + with: + gemini_api_key: ${{ secrets.GEMINI_API_KEY }} + bot_name: 'code-bot' + submit_review_verdict: true diff --git a/app.js b/app.js index d4376c3..7e1881e 100644 --- a/app.js +++ b/app.js @@ -1,5 +1,6 @@ const express = require('express'); const tasksRouter = require('./routes/tasks'); +const tagsRouter = require('./routes/tags'); const app = express(); const PORT = process.env.PORT || 3000; @@ -11,6 +12,7 @@ app.get('/health', (req, res) => { }); app.use('/tasks', tasksRouter); +app.use('/tags', tagsRouter); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); diff --git a/routes/tags.js b/routes/tags.js new file mode 100644 index 0000000..5b67493 --- /dev/null +++ b/routes/tags.js @@ -0,0 +1,53 @@ +const express = require('express'); +const router = express.Router(); + +// In-memory tag store +let tags = []; +let nextId = 1; + +// GET /tags +router.get('/', (req, res) => { + res.json(tags); +}); + +// GET /tags/:id +router.get('/:id', (req, res) => { + const tag = tags.find(t => t.id == req.params.id); + if (!tag) return res.status(404).json({ error: 'Tag not found' }); + res.json(tag); +}); + +// POST /tags +router.post('/', (req, res) => { + const { name, color } = req.body; + if (!name) { + return res.status(400).json({ error: 'Name is required' }); + } + const tag = { + id: nextId++, + name: name, + color: color || '#000000', + createdAt: new Date().toISOString() + }; + tags.push(tag); + res.status(201).json(tag); +}); + +// PATCH /tags/:id +router.patch('/:id', (req, res) => { + const tag = tags.find(t => t.id == req.params.id); + if (!tag) return res.status(404).json({ error: 'Tag not found' }); + if (req.body.name) tag.name = req.body.name; + if (req.body.color) tag.color = req.body.color; + res.json(tag); +}); + +// DELETE /tags/:id +router.delete('/:id', (req, res) => { + const idx = tags.findIndex(t => t.id == req.params.id); + if (idx === -1) return res.status(404).json({ error: 'Tag not found' }); + tags.splice(idx, 1); + res.status(204).send(); +}); + +module.exports = router;