04 — Your first contribution to someli-api¶
A walkthrough for taking your first ticket end-to-end. Your goal is not to be heroic; it is to prove you can run the loop: edit → run → verify → PR.
1. Pick a small first task¶
Ideal first tickets, in rough order of difficulty:
- Doc fix. Find a typo, an outdated env var, or a "[VERIFY]" marker in the audit subtree under
../../audit/someli-api/. Fix it. Open a PR againstsomeli-doc(this repo). - A
console.logcleanup.../../code-inspect/someli-api.mdlists specificconsole.loglines that ship PII to production. Pick one, remove it (or wrap behindif (process.env.NODE_ENV !== 'production')). PR againstsomeli-api'sdev_api. - A new healthcheck field. Add a build-version or git-SHA field to
GET /health. Touchesserver.js. Small but real. - A small endpoint addition. Talk to your lead about a "no-brainer" feature flag or constant lookup endpoint they want.
Avoid for your first PR: any job_*.js, anything touching Paddle/Stripe webhooks, anything that runs against helper/aiLogics.js (it's a 4000-line drift surface).
2. The edit-run-verify loop¶
cd ~/src/someli/someli-api
# 1. Branch
git checkout dev_api
git pull origin dev_api
git checkout -b fix/first-pr-typo
# 2. Edit a file in your editor
# 3. Run
yarn start # nodemon — auto-restarts on save
# 4. Verify
curl http://localhost:5002/health
# or whatever the changed endpoint is
Read the nodemon output as you edit. Every save triggers a restart. If you see [nodemon] app crashed - waiting for file changes, you have a syntax error or a runtime exception on boot — read the stack trace.
3. Entry points to know — a 30-minute reading tour¶
Open these in your editor in order. Don't try to understand them top-to-bottom — just scroll through each so the next time you grep, you know what you're looking at.
server.js(under 200 lines). The whole boot sequence. The single most important file in the repo.conf.js(very short). All env vars in one place.routes/routes.js— findapiRoutes.prototype.init = function()(around line ~100). Scroll through the next ~13,000 lines. You won't read it; you just need to know it exists and the shape.routes/auth.js— findrouter.use(auth)at line 78. Same exercise: scroll the file, get the shape.middlewares/auth.js— short. Read it. This is the auth gate every authenticated request passes through.helper/tokenGenerator.js— short. Read it. This is how tokens are minted and verified.actions/actions.js— the CRUD layer. Read it.- One
job_*.jsof your choosing. Pickjob_facebook_publish.jsor similar. Read it cover to cover. They're each a self-contained example. ecosystem.config.js— PM2 manifest. Scan it.
After this tour, you can place 90% of new code correctly without asking.
4. Reading-around your task¶
For any non-trivial task, before you edit:
- Grep across the whole platform for the feature you're touching: You might find your feature already exists, or that another repo has the same code that needs updating.
- Open the audit doc. Each topic has a dedicated file under
../../audit/someli-api/. For example, if your task touches publishing →../../audit/someli-api/jobs-inventory.md. If it touches RAG →../../audit/someli-api/rag-pipeline.md. - Check code-inspect. If your file is in
../../code-inspect/someli-api.md, there might be a known bug nearby that you should NOT trip over.
5. Manual testing¶
There is no test suite. You are the test suite. Always exercise:
- The happy path — does the changed endpoint return the expected response?
- The auth-failure path — does it return 401 without a valid token?
- The bad-input path — does it return 400 on malformed input?
- The DB-error path — if you stop the MySQL container, does it return 500 cleanly rather than hanging?
For things you can't test locally (Paddle webhooks, real social publishing), document the manual test plan in the PR description and ask for a UAT verification before merging to main.
6. Useful local helpers¶
A scratch script¶
When you need to call an internal function ad-hoc, write a temporary scratch.js at the repo root:
require('dotenv').config();
const { someFunction } = require('./helper/helper');
(async () => {
const result = await someFunction(/* args */);
console.log(JSON.stringify(result, null, 2));
})();
Run with node scratch.js. Add scratch.js to your local .gitignore (don't commit it).
Talking to the DB¶
Or use a GUI: MySQL Workbench, TablePlus, DBeaver, or the VS Code MySQL extension. The schema reference: ../../audit/someli-api/data-model.md.
7. Opening the PR¶
After the git workflow doc:
git add -p # review what you're about to commit
git commit -m "Fix typo in routes/routes.js docstring"
git push -u origin fix/first-pr-typo
# Open PR on github.com/Someli-ai/someli-api targeting dev_api
PR description template (informal, but include these):
## Why
Brief description of the bug / feature.
## What changed
- `routes/routes.js`: ...
- `helper/helper.js`: ...
## Manual test plan
1. `yarn start`
2. `curl ...`
3. Confirm response is `...`
## Related
- Ticket: ...
- Code-inspect finding: ...
8. After the PR is merged¶
- Watch the dev deploy. Jenkins (or GitHub Actions, for
someli-api) will SSH into the Lightsail dev box and restart. The deploy logs are in Jenkins. - Re-run your manual test against the dev URL. Verify it's actually live.
- Pull
dev_apilocally so your next branch is current:
9. Common first-PR mistakes¶
| Mistake | Why it's a problem | Avoid by |
|---|---|---|
Committing your .env |
Leaks every secret | .env should already be in .gitignore; double-check with git status |
| Adding a new env var without telling anyone | The next deploy fails | Mention new env vars at the top of the PR description |
Editing someli-api/helper/X.js without checking Someli-admin-api/helper/X.js |
The same bug remains in admin-api | Always check ../../audit/CODE-OVERLAP-MATRIX.md for shared-lineage files |
Changing middleware order in server.js |
Breaks webhook signature verification silently | Don't touch server.js middleware order; if you really must, get a senior to review carefully |
Adding a new console.log(req.body) for debugging and leaving it in |
Leaks user data to production logs | Remove before pushing; or use a temporary debug-<feature>.log file pattern |
Adding sync-mysql to new code |
Blocks the event loop | Use mysql2/promise for any new query |
| Picking up a job that runs on schedule and editing it without disabling the cron locally | The job runs against your dev DB on its real schedule and surprises you | Comment out the cron.schedule(...) call while iterating |
Next¶
→ 05-where-to-look.md — the troubleshooting routing table.