Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Description

Procurement API v6 is the backend service for vendor, contract, invoice, renewal, and dashboard workflows. This service is used by the procurement platform-ui sub-app, interal to Topcoder staff.

Routes

All business routes are served under /v6/procurement and require bearer auth.

System

  • GET /v6/procurement/health checks service and database readiness.
  • /v6/procurement/api-docs exposes Swagger documentation.

Dashboard

  • GET /v6/procurement/dashboard returns vendor count, active contract count, pending/overdue invoice counts and totals, expiring contract preview rows, and active renewal count.

Vendors

  • GET /v6/procurement/vendors lists vendors.
  • GET /v6/procurement/vendors/:id returns one vendor.
  • POST /v6/procurement/vendors creates a vendor.
  • PUT /v6/procurement/vendors/:id replaces a vendor.
  • DELETE /v6/procurement/vendors/:id hard-deletes a vendor.

Contracts

  • GET /v6/procurement/contracts lists contracts with vendor summaries and derived lifecycle.
  • GET /v6/procurement/contracts/expiring?days=30 lists active contracts whose end date falls inside the expiry window.
  • GET /v6/procurement/contracts/:id returns one contract.
  • POST /v6/procurement/contracts creates a contract.
  • PUT /v6/procurement/contracts/:id replaces a contract.
  • DELETE /v6/procurement/contracts/:id hard-deletes a contract.

Invoices

  • GET /v6/procurement/invoices lists invoices with vendor, optional contract, and derived payment-state summaries.
  • GET /v6/procurement/invoices?state=pending filters by derived invoice state.
  • GET /v6/procurement/invoices/overdue lists overdue invoices.
  • GET /v6/procurement/invoices/:id returns one invoice.
  • POST /v6/procurement/invoices creates an invoice.
  • PUT /v6/procurement/invoices/:id replaces an invoice.
  • DELETE /v6/procurement/invoices/:id hard-deletes an invoice.

Renewals

  • GET /v6/procurement/renewals lists renewals with contract and vendor context.
  • GET /v6/procurement/renewals/stages returns workflow stage metadata.
  • GET /v6/procurement/renewals/:id returns one renewal.
  • POST /v6/procurement/renewals creates a renewal at quotation and stamps quotationAt.
  • PUT /v6/procurement/renewals/:id replaces editable renewal fields without changing workflow stage.
  • Create and replace normalize newStartDate and newEndDate to the submitted business dates at midnight UTC.
  • PATCH /v6/procurement/renewals/:id/stage moves one workflow stage forward or backward. po_release is terminal and finalizes contract dates plus optional value in one transaction, applying the normalized renewal dates to the contract.
  • DELETE /v6/procurement/renewals/:id hard-deletes a renewal.

Derived States

The API does not persist alert-only states:

  • Contract lifecycle is derived from stored Contract.status and endDate.
  • Invoice paymentState is derived from stored Invoice.status, dueDate, and paidDate.
  • Active renewals are renewals whose stage is not po_release.

Money fields are serialized as numbers in read models and dashboard totals.

Access

Health remains unguarded. Every business controller uses ProcurementAccessGuard and exact scope metadata on each handler.

Caller type Required access Notes
Human procurement-user or procurement-admin role Role claims may be supplied through role or roles.
Machine read procurement:read scope Write scope is not treated as implicit read access.
Machine write procurement:write scope Required for create, replace, delete, and renewal stage movement.
Missing route scope metadata Denied for machine callers Business handlers must declare explicit scopes.

Authentication is delegated to the shared bearer-token middleware. Local login and local user-management endpoints are intentionally absent from this service.

Configuration

Required:

  • DATABASE_URL - PostgreSQL connection string used by Prisma.
  • AUTH_SECRET - JWT secret used by tc-core-library-js.
  • VALID_ISSUERS - JSON array or comma-separated issuer list accepted by the auth middleware.

Optional:

  • PORT - HTTP port, default 3000.

Local Development

Node.js 26.12.1 and pnpm 11.15.1 are the supported local toolchain. Run nvm use, install dependencies with pnpm install, generate Prisma with pnpm prisma generate, and start the service with pnpm start:dev.

Container Runtime

The production image uses Alpine 3.24's patched Node.js 26.12.1 package and runs as the unprivileged app user (UID 10001). Build-only package managers and development dependencies are excluded from the final image.

Shared authentication and bus client (v6 refresh)

This branch uses tc-core-library-js 4.0.0-rc.1. Use its named createJwtVerifier / createJwtAuthenticator, createM2MClient, and createBusApiClient exports for shared authentication and bus API publishing. Service-specific roles, scopes, sessions and ownership checks remain in this service. The former bus wrapper dependency and local JWT cryptography must not be reintroduced.

RSA verification requires an exact configured issuer and audience (JWT_AUDIENCE for client tokens, AUTH0_AUDIENCE for machine/API tokens, or this service's explicit issuer-policy settings). HMAC secrets must be at least 32 bytes; no default secret is supplied. Expiry is enforced. Machine identity comes from the shared verifier, not the presence of scopes. Supply real development credentials through the service's existing environment configuration before deployment.

Bus publishers use createBusApiClient(config).postEvent(event) with the existing event envelope and optional key. Configure BUSAPI_URL for v6 and the existing OAuth credentials/token provider. The client uses bounded HTTPS requests and does not retry POSTs automatically. Application retry/outbox behavior remains local.

See the core migration guide for the API mapping, compatibility requirements, and rollout scope.

Alpine Node runtime packages

Container stages that install Node through APK constrain nodejs-current to the major version in NODE_VERSION, rather than an exact Alpine package revision. Alpine replaces older patch packages in its repositories; the compatible pin allows current security patches while a build-time check rejects a different Node major. The runtime keeps Alpine's dynamically linked Node and system libraries. Existing non-root users and application entrypoints are preserved. Build stages using a versioned official Node image retain their configured version, and pnpm build arguments are explicitly declared in the consuming stage.

Dependency security checks

The frozen pnpm graph pins the shared Topcoder library to an immutable revision and applies patched runtime and tooling dependencies. Older tooling uses a tested minimatch adapter. Run pnpm audit and pnpm test:dependency-compat alongside the existing lint, build and test checks when changing dependencies. Container bases are pinned by digest, and Alpine packages receive security updates during image builds.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages