Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
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
19 changes: 16 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
# Description: Example of .env file
# Example .env file for local development and tests

# MongoDB URI
# MongoDB (optional)
MONGO_URI=mongodb://localhost:27017/your-database-name

# Auth Plugin
# OpenID Connect (used by the auth plugin)
# AUTH_DISCOVERY_URL should point to the provider's discovery document (/.well-known/openid-configuration)
AUTH_DISCOVERY_URL=https://login.microsoftonline.com/c917f3e2-9322-4926-9bb3-daca730413ca/v2.0/.well-known/openid-configuration
AUTH_CLIENT_ID=b4bc4b9a-7162-44c5-bb50-fe935dce1f5a

# When true, the auth plugin skips remote discovery and verification (useful for local testing)
AUTH_SKIP=true

# Optional runtime controls
NODE_ENV=development
PORT=3000

# Test helpers (optional)
# Provide these only when running integration tests that require a real token/user.
TEST_AUTH_TOKEN=
TEST_AUTH_USER=
67 changes: 67 additions & 0 deletions .github/workflows/docs-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: docs:publish

on:
push:
branches:
- main
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

jobs:
detect-quota:
# Probe the hosted runner so we can decide whether to use hosted or self-hosted.
runs-on: ubuntu-slim
steps:
- name: Quota probe
id: quota_probe
run: |
echo "probe"

build-and-publish:
needs: detect-quota
# NOTE: do not set `continue-on-error` on detect-quota (see docs)
runs-on: ${{ needs.detect-quota.result == 'success' && 'ubuntu-slim' || 'self-hosted' }}
steps:
- uses: actions/checkout@v4

- name: Use Node
uses: actions/setup-node@v4
with:
node-version: 24

- name: Enable Corepack
run: |
corepack enable
corepack install

- name: Enable Node cache
uses: actions/setup-node@v4
with:
cache: yarn

- name: Install dependencies (Corepack + Yarn)
run: |
corepack prepare yarn@stable --activate
corepack yarn install --frozen-lockfile

- name: Build project
run: corepack yarn build

- name: Generate TypeDoc
run: corepack yarn docs:typedoc

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: api-docs
path: docs/api

- name: Publish to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./docs/api
62 changes: 62 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: docs

on:
push:
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
detect-quota:
# Probe the hosted runner so we can decide whether to use a hosted
# runner or fall back to self-hosted. The job should fail if quota is exhausted.
runs-on: ubuntu-slim
steps:
- name: Quota probe
id: quota_probe
run: |
echo "probe"

build:
needs: detect-quota
# NOTE: Do not set `continue-on-error: true` on the `detect-quota` job.
# If `continue-on-error` is enabled the job result will always be
# 'success', which defeats detection (we rely on `needs.detect-quota.result`).
runs-on: ${{ needs.detect-quota.result == 'success' && 'ubuntu-slim' || 'self-hosted' }}
steps:
- uses: actions/checkout@v4

- name: Use Node
uses: actions/setup-node@v4
with:
node-version: 24

- name: Enable Corepack
run: |
corepack enable
corepack install

- name: Enable Node cache
uses: actions/setup-node@v4
with:
cache: yarn

- name: Install dependencies
run: |
yarn install --frozen-lockfile

- name: Build project
run: |
yarn build

- name: Generate TypeDoc
run: |
yarn docs:typedoc

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: api-docs
path: docs/api
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,7 @@ dist
!.yarn/releases
!.yarn/sdks
!.yarn/versions

# Generated TypeDoc output (do not commit generated API docs)
docs/api/
docs/api/**
32 changes: 12 additions & 20 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# How to Contribute

Thanks for reading this, because we really need everyone to follow some collaboration guidelines to make our codebase
maintainable, clean and concise.
Thanks for taking a moment to read this. Following these collaboration guidelines helps keep the codebase maintainable,
clean, and easy to review.

The standard workflow to contribute to the project is as follows:

1. Create an issue to track the things (feature, bug or something else) you are working on. This also allows other
contributors to know what you are working on, and to potentially offer suggestions or help.
2. On the right hand side of the issue page, there is a button that allows you to create a new branch for the issue.
This will automatically create a new branch with the issue number and title. I strongly recommend you to use this
feature instead of creating a branch manually, because it will make it easier to track the issue that you are working
on.
2. On the right hand side of an issue page there is a button to create a branch for that issue. It will create a branch
named from the issue number and title. We recommend using that feature (rather than creating branches manually) to
make it easier to track work against the originating issue.
3. Make your changes in the new branch. Ideally, your commit messages should follow
the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) specification. We will rebase your PR
later if your commits are well-organized and the messages are well-formatted. Otherwise, we may ask you to fix them,
Expand All @@ -34,8 +33,8 @@ but we will try our best to achieve the following goals:
- Use iterative methods on collections instead of loops whenever possible.
- Avoid side effects in a function as much as possible.

That's not only because functional programming is cool, but also because it reduces the complexity of the code, and
makes it easier to reason about the code. For example, you should _never_ do:
Apart from functional programming being cool, this reduces complexity and
makes code easier to reason about. For example, you should _avoid_:

```typescript
const numbers = [1, 2, 3]
Expand Down Expand Up @@ -64,16 +63,12 @@ During the PR review process, we make use of GitHub comments to track suggestion
The general principles are the following:

- If the comment is a change suggestion...

- If it's clear and uncontroversial how to apply the suggestion, you should resolve the comment after you have made
- If it's clear and uncontroversial how to apply the suggestion, you should resolve the comment after you have made
the corresponding changes to the PR.

- If you are not 100% sure that you have applied the suggestion correctly, leave a comment asking it. Do not resolve
- If you are not 100% sure that you have applied the suggestion correctly, leave a comment asking it. Do not resolve
the comment in this case.

- If you don't fully understand or agree with the suggestion, reply to the comment with your questions and
- If you don't fully understand or agree with the suggestion, reply to the comment with your questions and
rebuttals. Do not resolve the comment in this case.

- If the comment is a clarification request, answer it. Do not resolve the comment in this case. We will either come
back with further questions or suggestions, or close the comment ourselves if we find your answer satisfactory.

Expand All @@ -86,8 +81,5 @@ Please make sure your code passes all automated CI tests (unless under special c
You may trigger them by simply pushing your commits to a branch, or by opening a PR. Reviewing a PR that doesn't pass
tests is a waste of time for everyone involved.

During code review, it is not supposed to happen that we have to keep coming back to your PR, continually finding more
problems more unpolished changes, and having to go through lots of back-and-forth interactions this way. This will only
lead to growing frustration on both ends.


During code review, please try to address issues thoroughly before requesting another round of review. This reduces
unnecessary back-and-forth and speeds up the process for everyone.
75 changes: 46 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,69 @@
# USThing Template API
# template-api

The template repository for USThing backend services, powered by Fastify.
<!-- NOTE: If you use this repository as a template, replace `USThing/template-api` with your own GitHub owner/repo in the badge URLs. -->
[![CI](https://github.com/USThing/template-api/actions/workflows/check.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/check.yml) [![Docs](https://github.com/USThing/template-api/actions/workflows/docs-publish.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/docs-publish.yml) [![Release](https://github.com/USThing/template-api/actions/workflows/release.yml/badge.svg)](https://github.com/USThing/template-api/actions/workflows/release.yml) [![Docs site](https://img.shields.io/badge/docs-site-blue)](./docs/api/index.html)

## Available Scripts
A concise Fastify + TypeScript starter used by USThing backend services. This repository provides a minimal, well-tested scaffold with recommended scripts, linting, and CI configuration.

In the project directory, you can run:
## Prerequisites

### `yarn run dev`
- Node.js (see `engines` in `package.json`)
- Yarn via Corepack

To start the app in dev mode.
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
Enable Corepack (recommended) and the Yarn version used by this repo:

### `yarn run start`
```bash
corepack enable
corepack prepare yarn@stable --activate
```

For production mode
## Quickstart (local)

### `yarn run test`
```bash
corepack enable
yarn install
yarn build
yarn start
```

Run the test cases.
## Developer workflow

### `yarn run lint`
- Start dev mode (watch + Fastify): `yarn dev`
- Run tests: `yarn test`
- Lint: `yarn lint` (fix: `yarn lint:fix`)

Run the linter.
## Automatic API docs

Note that the format of the code will also be checked.
API docs are generated from source by TypeDoc and published by CI. To generate locally:

### `yarn run lint:fix`
```bash
yarn docs:typedoc
```

Run the linter and fix the issues.
Generated docs are placed under `docs/api` (CI publishes these artifacts — do not commit generated files).

Note that the format of the code will also be checked and fixed.
## Project layout

## Environment Variables
- `src/` — application code (routes, plugins, utils)
- `src/app.ts` — Fastify app and plugin registration
- `routes/` — route modules
- `test/` — tests and helpers
- `docs/` — human-authored guides and docs
- `.env.example` — example environment variables

For Fastify-level environment variables, please refer to the [fastify-cli documentation](https://github.com/fastify/fastify-cli).
## Environment

For the application-level environment variables, please refer to the `.env.example` file.
Tests and some dev helpers reference `TEST_AUTH_TOKEN` / `TEST_AUTH_USER`. See `docs/env-vars.md` for recommended env variables and CI secret usage. Keep secrets out of the repo and use your CI's secret manager.

## CI / CD
## Contributing

This template supports GitHub Actions for CI / CD. The available workflows are:
Follow `CONTRIBUTING.md` (commitlint, lint, tests). The project uses Conventional Commits for releases.

- Checks / eslint: Run ES Lint to check problems and the format of the code.
- Checks / commitlint: Run Commitlint to check the format of the commit messages.
- Checks / tests: Run unit tests of the project.
- Docker CI / docker: Build the Docker image and push it to the GitHub Container Registry.
- Release Please / release-please: Automatic releasing. See also [release-please](https://github.com/googleapis/release-please).
## Support

## Learn More
Open an issue on GitHub using the provided templates for bugs or feature requests.

To learn Fastify, check out the [Fastify documentation](https://fastify.dev/docs/latest/).
## Learn more

- Fastify: <https://www.fastify.dev/>
- Docs folder: `docs/` (detailed guides and examples)
16 changes: 16 additions & 0 deletions docs/ci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# CI workflows

The repository uses three primary GitHub Actions workflows in `.github/workflows/`:

- `check.yml` — runs on push and pull_request. It probes runner availability (a small `detect-quota` job) and then runs ESLint, commitlint, and tests. Each job uses a hosted-first → self-hosted fallback by selecting `runs-on` based on the probe result.
- `docker.yml` — builds and pushes container images (Buildx). It also probes runner availability and uses a hosted-first fallback. The workflow prepares Docker metadata (tags include sha, branch/ref, and PR tags) and pushes images to `REGISTRY`/`IMAGE_NAME`.
- `release.yml` — runs `googleapis/release-please-action@v4` on pushes to `main`. When a release is created the workflow tags versions and (optionally) builds/pushes images. See `release.yml` for the exact tagging and build steps.

## Key notes

- Hosted-first fallback: jobs use a small probe job (`detect-quota`) and set `runs-on` dynamically so CI prefers `ubuntu-latest` but can fall back to `self-hosted` when needed.
- Docker workflow permissions: the docker workflow requests permissions to push packages and to request an `id-token` for registry login; it logs into the registry using the workflow token by default.
- Release workflow: `release-please` creates release PRs or releases and exposes outputs such as `release_created`, `major`, `minor`, `patch`, `tag_name`, and `body` that downstream steps use.
- Tokens: the action uses the default `GITHUB_TOKEN` unless configured to use a PAT; if you need CI checks to run on Release PRs, configure a PAT as described in the action docs.

If a run fails, open the workflow run in GitHub Actions and inspect the primary (hosted) job logs first. Avoid committing generated artifacts; let CI produce and publish them.
Loading