7th Cavalry Apps (CavApps) is a Nextjs based collection of tools and apps designed to aid the 7th Cavalry Gaming Regiment in its day to day functions. In its current form, CavApps currently includes the Active Duty Roster (ADR) and a small collection of Roster Statistics. Future iterations of CavApps can include a more advanced statistics tool, an AWOL tracker, and a potential migration of S1 Documents among other possible tools. CavApps is currently structured as a Frontend-Backend architecture and includes basic authentication for enhanced security.
The live deployment can be found at https://apps.7cav.us/ and the backend at https://bff.apps.7cav.us/
NOTE: This documentation is written so that an average member of the 7th Cavalry should be able to make basic edits to CavApps. If you need help with a particular matter or believe this documentation could be improved, please message S6 Development Staff on Discord or on the Forums.
CavApps is a monorepo with two parts:
server/— an Express caching proxy ("BFF") that fetches roster data from the 7th Cavalry API and serves it from memory.client/— a Next.js 13 (App Router) app with three tools: the Active Duty Roster (ADR), Roster Statistics, and the Uniform Builder.
The client never talks to the 7th Cavalry API directly — it only talks to the server.
You need two tokens:
| Token | Purpose | Where it goes |
|---|---|---|
API_TOKEN |
Authenticates the server to api.7cav.us. A real 7th Cavalry API bearer. |
server env |
CLIENT_TOKEN |
Shared secret between the client and server. Can be any string you choose — it just has to match on both sides. | server env + client env |
To get your API_TOKEN:
- Log into your 7th Cavalry Gaming account (member-level, not a public account).
- Open your Connected Accounts and click "view account" for
auth.7cav.us. - Log into Keycloak and copy the provided API token.
Heads up on
.envformatting: useKEY=valuewith no spaces around the=and no surrounding quotes. A line likeAPI_TOKEN ='abc'(note the space) makes the variable nameAPI_TOKEN(with a trailing space), so Docker Compose treatsAPI_TOKENas unset and the server fails to start with a401 Unauthorized.
This is the fastest way to get a working dev environment — it builds and runs both the server and client for you, with hot-reload on the client.
-
Install Docker (Docker Desktop on macOS/Windows).
-
In the project root, create a
.envfile:API_TOKEN=your-7cav-api-token-here CLIENT_TOKEN=any-shared-secret-you-choose
-
Bring the stack up:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up
That's it. The override file (docker-compose.dev.yml) provisions the edge network locally, so no manual docker network create is needed. When it finishes:
- Client (CavApps index): http://localhost:3000
- Server (BFF): http://localhost:4000
The server must successfully load roster data on startup or it will exit and restart — if it keeps restarting, double-check your API_TOKEN (see the formatting note above).
Stop the stack with Ctrl+C, or from another terminal:
docker compose -f docker-compose.yml -f docker-compose.dev.yml down
docker-compose.ymlon its own is the production config and expects an externally managededgenetwork. For local dev always include the-f docker-compose.dev.ymloverride.
If you'd rather run the apps directly on your machine instead of in Docker:
- A valid 7th Cavalry Gaming account with member-level privileges.
- Node.js v18+.
- Your choice of IDE such as VSCode or neoVim.
You'll run the server and client in two separate terminals.
1. Server (server/):
cd server
npm install
API_TOKEN=your-7cav-api-token CLIENT_TOKEN=any-shared-secret node server.jsThe server listens on http://localhost:4000. Visiting it in a browser confirms it's up. (It reads API_TOKEN and CLIENT_TOKEN from the environment — export them in your shell or use a tool like dotenv / a .env loader of your choice.)
2. Client (client/):
Create client/.env.local with:
NEXT_PUBLIC_CLIENT_TOKEN=any-shared-secret-you-choose
COMBAT_API_URL=http://localhost:4000/roster/combat
RESERVE_API_URL=http://localhost:4000/roster/reserves
GROUP_API_URL=http://localhost:4000/roster/groups
CACHE_TIMESTAMP_URL=http://localhost:4000/cache-timestamp
NEXT_PUBLIC_INDIVIDUAL_API_URL=http://localhost:4000/roster/individualNEXT_PUBLIC_CLIENT_TOKEN must match the server's CLIENT_TOKEN. Then:
cd client
npm install
npm run devOpen http://localhost:3000 and you should see the CavApps index page. Happy coding!
For further documentation on Next.js, visit https://nextjs.org/docs
Since the ADR sources its data from the 7th Cavalry API and compares the API against a predefined billet list, the ADR is not aware when new billets are created or when older billets are moved.
For example, if a new company in 2-7 is created, the list the ADR compares against needs to be updated in order to display the membership of the new company.
To add a new billet to an existing category, you need to update the BilletBank.jsx file located in cavapps/client/app/reusableModules.
- Open
BilletBank.jsx. - Locate the array that corresponds to the category where you wish to add the new billet.
- Append the new billet ID to this array.
Suppose you want to add a new billet with an ID of 28 to the "Information Management Office Command" category. Update imoCommand as follows:
const imoCommand = ["5", "9"];const imoCommand = ["5", "9", "28"];To introduce a new category, both BilletBank.jsx and page.jsx located in cavapps/client/app/adr/page.jsx need to be updated.
-
In
BilletBank.jsx:- Add a new array for each subcategory and populate it with the requred billet IDs.
- Add a new object for the new category and append the subcategories as well as their titles to the new object. additionally, add a
collapsibleTitlewith the name of the new category into the object. - Add the new object to the billetbank object at the bottom of the file
-
In
adr/page.jsx:- Create a new
AdrListEntrywith the bBGroup value set to a string containing title of the new Object
- Create a new
You have been assigned the task of creating an entry in the ADR for 3rd Battalion. It has 3 companies, Alpha Bravo and Charlie. Each have their own designated billet ID's. (in a live setting, each company can have strings that are dozens of entries each in length)
In BilletBank.jsx:
//3-7
const threeSevenCommand = ['1', '2', '3'] //placeholder values
const alpha3 = ['4','5','6']
const bravo3 = ['7','8','9']
const charlie3 = ['10','11','12']
const threeSeven = {
positionIds: [threeSevenCommand, alpha3, bravo3, charlie3],
positionTitles: [
"3-7 Headquarters",
"Alpha Company",
"Bravo Company",
"Charlie Company",
],
collapsibleTitle: "Third Battalion",
};
...
const billetBankObject = {
regi: regi,
oneSeven: oneSeven,
twoSeven: twoSeven,
threeSeven: threeSeven,
...
};In adr/page.jsx:
// important: make sure the bBGroup string matches the object name in the billetBank section
...
<AdrListEntry bBGroup={"oneSeven"} milpacArray={milpacArray} />
<AdrListEntry bBGroup={"twoSeven"} milpacArray={milpacArray} />
<AdrListEntry bBGroup={"threeSeven"} milpacArray={milpacArray} />
...Note: Ensure that you add these elements in the proper locations in
page.jsxto maintain the formatting.
NOTE: If you are making changes to CavApps and want said changes put on the live version, submit a pull request. This section is intended for S6 Staff for deployment testing purposes.
In order to deploy CavApps on a server, you need the following:
-
A linux (preferably ubuntu) based server with the following:
- Access via SSH
- Sudo level permissions
- Minimum 2GB RAM
-
Alongside the following packages:
- Docker Engine
- nodejs
- npm
- git
sudo apt install git npm nodejs -
A 7th Cavalry API token (see Authorization)
Once the required packages are installed, clone the repo
git clone https://github.com/Vercin-G/CavApps-Test
First, install prerequisites:
In CavApps-Test/server/:
npm install
In CavApps-Test/client/:
npm install
Next, create a .env file in the project root with your tokens (see Authorization):
API_TOKEN=your-7cav-api-token-here
CLIENT_TOKEN=any-shared-secret-you-chooseThe production docker-compose.yml wires the client to reach the server over the internal Docker network (http://server:4000/...), so you do not need to set the per-URL client variables by hand for a Docker deployment — they're defined in the compose file.
Then, from the project root:
docker compose upProduction
docker compose up(without the dev override) expects an externally managededgenetwork — create it once withdocker network create edgeif it doesn't already exist on the host.
And you should be good! Simply navigate to your server in your browser and the index page should show. The server side should be accessable via port 4000.
NOTE: On slower servers, the generation of nextjs static pages may cause a hang. This is normal. Give it a few seconds.
The Roster Statistics section is currently pending rewrite to include more information. Stay Tuned!
CavApps has several goals in mind for the future. Here are some examples.
- Roster Statistics which draw from a 7th Cavalry Operated database. Providing historical numbers on top of current figures
- Implementation of an AWOL tracker
- Implementation of keycloak systems to allow for the operation of internal documents. E.g. moving S1 spreadsheets into internal tools which are authenticated by keycloak.