Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.git
build
node_modules
npm-debug.log
yarn-error.log
112 changes: 112 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# Agent Notes

## Project Overview

Neuvue-Queue is a TypeScript/Node REST API backed by MongoDB. It uses Restify for HTTP routing, Mongoose for persistence, Auth0/JWT middleware for protected routes, and Swagger UI/OpenAPI files for API docs.

The main runtime path is:

- `src/bin/neuvuequeue.ts`: reads configuration via `config` and starts the service.
- `src/neuvuequeue.ts`: connects to MongoDB, configures Restify middleware, serves Swagger/static files, and attaches controllers.
- `src/controllers/`: route registration and request handlers.
- `src/models/`: Mongoose schemas.
- `src/utils/`: shared middleware, serializers, file handlers, mixin helpers, and Mongo URI creation.
- `docs/neuvuequeue.yaml`: OpenAPI documentation served at `/docs/neuvuequeue.yaml`.
- `public/index.html`: Swagger UI shell served from `/`.

## Setup And Commands

Use Yarn v1 with the checked-in `yarn.lock`.

```sh
yarn install
yarn run build
yarn run tslint
yarn run unit-test
yarn run test
```

Useful commands:

- `yarn run build`: TypeScript compile to `build/`.
- `yarn run watch`: TypeScript watch mode.
- `yarn run tslint`: TSLint project lint.
- `yarn run unit-test`: unit tests matching `test/**/*.unit.test.ts`.
- `yarn run integration-test`: integration tests matching `test/**/*.integration.test.ts`.
- `yarn run test`: all `test/**/*.test.ts` files.
- `docker-compose up -d`: local MongoDB plus API service.

For local bare-metal runs, start MongoDB separately, then:

```sh
yarn install
yarn run build
node ./build/bin/neuvuequeue.js
```

## Runtime Configuration

Default config lives in `config/default.json`. Environment variable mappings live in `config/custom-environment-variables.json`.

Important environment variables:

- `NEUVUEQUEUE_MONGODB_DATABASE`
- `NEUVUEQUEUE_MONGODB_HOST`
- `NEUVUEQUEUE_MONGODB_PORT`
- `NEUVUEQUEUE_SERVER_HOST`
- `NEUVUEQUEUE_SERVER_PORT`
- `NEUVUEQUEUE_LOG_LEVEL`
- `AUTH0_DOMAIN`
- `AUTH0_AUDIENCE`
- `AUTH0_CLIENTID`
- `AUTH0CLIENTSECRET`

Auth-protected routes expect Auth0 JWTs with `permissions` and `allowed_namespaces` payload fields. Namespace authorization is enforced in `CRUDMixin.ensureNamespaceAuthorizedForPatch` and `CRUDMixin.insert`.

## Code Style

- TypeScript target is ES6/CommonJS with `noImplicitAny` and `strictNullChecks` enabled.
- Follow the existing TSLint rules: double quotes, 120-character max line length, no interface `I` prefix.
- Prefer existing Restify/Mongoose callback style when editing nearby controller code unless a wider refactor is requested.
- Keep model schema changes in `src/models/*` synchronized with route behavior and `docs/neuvuequeue.yaml`.
- Do not edit `build/` for source changes. It is compiled output.
- Preserve the current API shape and response behavior unless the task explicitly asks for a breaking change.

## Architecture Notes

Controllers extend `Controller` through `mix(Controller).with(...)`. Shared CRUD behavior is in `src/controllers/mixins.ts`:

- `query` supports `q` as JSON, pagination via `p`/`pageSize`, `populate`, `select`, and `sort`.
- `detail` supports `populate`, `select`, and `sort`.
- `insert` validates Mongoose documents, checks namespace permissions, then uses `collection.insertMany`.
- `deactivate` soft-deletes by setting `active: false`.

Current controller roots:

- `/points` -> `PointController`
- `/tasks` -> `TaskController`
- `/auth` -> `AuthController`
- `/differstacks` -> `DifferStackController`
- `/agents` -> `AgentsJobController`

When adding a resource, update all of:

- `src/models/index.ts`
- `src/controllers/index.ts`
- A controller in `src/controllers/`
- A model in `src/models/`
- `docs/neuvuequeue.yaml`

## Testing Guidance

Unit tests currently cover utility behavior in `test/utils`. Add focused unit tests for pure helpers and lower-level behavior. For controller or auth changes, prefer tests that exercise route behavior and authorization paths, and document any required MongoDB/Auth0 setup if a true integration test is needed.

Run at least `yarn run build` and the most relevant test command before handing off changes. Run `yarn run tslint` when touching TypeScript.

## Gotchas

- `docker-compose.yml` maps the API on host port `80`, while the README mentions port `9005`; check the compose file before relying on README port text.
- `docs/neuvuequeue.yaml` may lag behind schemas; verify enum values and field names against `src/models/*`.
- Auth0 token exchange in `AuthController` uses a hard-coded Auth0 token URL and env vars for client credentials.
- Some protected route detail/delete behavior is inconsistent across controllers; inspect the specific controller before assuming auth middleware is attached.
- `controllers/index.ts` option keys use `differstack` and `agentsjob` lookups even though the interface names use `differ_stack` and `agents_job`.
15 changes: 8 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
FROM node:16.10-alpine
LABEL maintainer "Daniel Xenes <daniel.xenes@jhuapl.edu>"
FROM node:20.19-bookworm-slim
LABEL maintainer="Daniel Xenes <daniel.xenes@jhuapl.edu>"

ARG YARN_STRICT_SSL=false

RUN apk add --no-cache su-exec tini
EXPOSE 80
ENV NODE_CONFIG_DIR=/etc/neuvuequeue
VOLUME [ "/etc/neuvuequeue" ]

COPY package.json tsconfig.json tslint.json yarn.lock /opt/neuvuequeue/
COPY package.json tsconfig.json tsconfig.test.json tslint.json yarn.lock /opt/neuvuequeue/
COPY src/ /opt/neuvuequeue/src/
COPY docs/ /opt/neuvuequeue/docs/
COPY public/ /opt/neuvuequeue/public/
COPY config/ /etc/neuvuequeue/

WORKDIR /opt/neuvuequeue
RUN yarn \
RUN yarn config set strict-ssl "${YARN_STRICT_SSL}" \
&& yarn install --frozen-lockfile \
&& yarn run build

ENTRYPOINT [ "/sbin/tini", "--" ]
CMD [ "node", "/opt/neuvuequeue/build/bin/neuvuequeue.js" ]
CMD [ "node", "/opt/neuvuequeue/build/bin/neuvuequeue.js" ]
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,8 @@ For deploying neuvue-queue in a production environment, see [automatizar](https:

**v1**

Added `tags` field.
Added `tags` field.

**v2**

Added optional `adaptive_priority` field for server-side weighted priority scoring with prior provenance.
31 changes: 23 additions & 8 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,24 +1,39 @@
version: "3"
services:
mongodb:
container_name: mongodb
image: mongo:3.6
image: mongo:8.0
restart: on-failure
volumes:
- mongo-data:/data/db
- /data/archive:/data/archive/
- mongo-data-v8:/data/db
- ${NEUVUEQUEUE_ARCHIVE_DIR:-/Users/xenesd1/Backups}:/data/archive
healthcheck:
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping').ok"]
interval: 10s
timeout: 5s
retries: 5
neuvuequeue:
container_name: neuvuequeue
build: "."
build:
context: "."
init: true
ports:
- 80:80
- "9005:80"
restart: on-failure
depends_on:
- mongodb
mongodb:
condition: service_healthy
environment:
NEUVUEQUEUE_MONGODB_DATABASE: neuvue
NEUVUEQUEUE_MONGODB_HOST: mongodb
NEUVUEQUEUE_MONGODB_PORT: 27017
NEUVUEQUEUE_SERVER_HOST: 0.0.0.0
NEUVUEQUEUE_SERVER_PORT: 80
# AUTH0_DOMAIN: dev-oe-jgl7m.us.auth0.com
# AUTH0_AUDIENCE: https://queue.neuvue.io
healthcheck:
test: ["CMD-SHELL", "node -e \"fetch('http://127.0.0.1:80/docs/neuvuequeue.yaml').then((r) => process.exit(r.ok ? 0 : 1)).catch(() => process.exit(1))\""]
interval: 10s
timeout: 5s
retries: 5
volumes:
mongo-data:
mongo-data-v8:
Loading