Web app frontend for Grottocenter, the Wiki database made by cavers for cavers, maintained by Wikicaves.
This project uses Yarn & Yarn workspaces.
Note
For the backend server see Grottocenter/grottocenter-api.
- Install Node.js (use the version in
.nvmrc) and Yarn - Install Git (v2.32.0 minimum for the commit hooks)
- Run
yarnto install dependencies - Run
yarn startto launch the app
The root package.json defines the supported Node versions in
engines.node for this Yarn monorepo, including its private web-app workspace.
CI uses the exact version in .nvmrc. For a Node security update,
update .nvmrc and the root engines.node, then verify the runtime versions in
the CI logs. GitHub Actions also have their own Node runtimes,
which are supplied by the runner and are not changed by setup-node.
Cypress/Electron also bundles Node separately. Check its version with
npx --no-install cypress version when updating Cypress; .nvmrc does not
update that runtime.
By default the app uses the production API as backend. To change it, edit the VITE_API_URL variable in packages/web-app/.env.
- Main web app
- Configurations:
eslint-configprettier-configts-config
startStart Grottocenter FrontbuildBuild the Grottocenter FrontlintCheck linting ruleslint:fixSame aslintbut will also try to fix errorse2e:runRun the end-to-end test suite (requires a running app)e2e:openOpen the end-to-end test suite browser (requires a running app)testRun unit tests (single run, no watch mode). Filter by pattern:yarn test -- --testPathPattern=<pattern>storybookStart Storybooktranslations:sync-with-enCompare a translation file withen.jsonto check synchronization (usage:yarn translations:sync-with-en <target-file>)translations:update-enScan JSX files for translation keys and add missing ones topackages/web-app/public/lang/en.json(automatically sorts the file afterwards)translations:sortSort translation file keys alphabetically (case-insensitive):node scripts/translations/sort.js <path-to-json-file>
GitHub Actions runs on push and pull requests targeting develop:
- Lint
- Unit tests & end-to-end tests (Cypress)
- CodeQL analysis
- Translations sync
- Azure Static Web Apps deploy
- Release (tag + changelog on every merge into
develop)
The lint and translation job names (build (24) and check-translations (24))
are kept stable for branch protection, independently of the version in .nvmrc.
Coordinate any rename with the required checks configured on develop.
Only on app-x.y.z tags:
- TWA build
Grottocenter is packaged for the Google Play Store as a Trusted Web Activity
that wraps the deployed PWA. See twa/README.md for the full
guide: PWA/service-worker setup, keystore generation, Play App Signing,
assetlinks.json, the CI build workflow, and secret sharing.
The workflow builds with the Node version from .nvmrc and the repository's Yarn
configuration, then uploads packages/web-app/dist with skip_app_build: true.
This avoids Oryx selecting an older Node version in the deployment container.
The current Azure plan allows at most three preview environments. If deployment
reports that this limit is reached, free an unused preview in Azure and rerun
the failed deployment job. Before merging deployment changes, verify that
the preview loads and that refreshing a client-side route such as /ui/entrances
works.
This project is set up for use with any AI agent, including Claude Code.
AGENTS.md— project conventions, architecture, vocabulary, git workflow, and agent checklist. Read by agents for any work in this repo.packages/web-app/AGENTS.md— web-app specifics: i18n workflow, Redux patterns, testing, env vars, UI/UX patterns. Read when working insidepackages/web-app/.CONTRIBUTING.md— human-oriented setup guide (IDE, browser extensions, Transifex).
These files can and should be updated when conventions change, new patterns are established, or the tech stack evolves.
Reusable agent workflows are defined in .agents/skills/:
| Skill | Invocation | Description |
|---|---|---|
code-review |
/code-review <PR-number> |
Fetches the diff, reads project conventions, and submits a structured review to GitHub |
github-workflow |
/github-workflow |
Guides through the Grottocenter commit/branch/PR conventions |
Claude Code loads skills from .claude/skills/. A project hook automatically mirrors any file saved under .agents/skills/ into .claude/skills/ so both stay in sync.
To sync manually (e.g. after cloning or pulling new skills):
# bash/zsh
cp -r .agents/skills/. .claude/skills/
# PowerShell
Copy-Item -Recurse -Force .agents\skills\* .claude\skills\- Create or edit the
SKILL.mdin.agents/skills/<skill-name>/. - The hook copies it to
.claude/skills/automatically on the next agent write. If working outside Claude Code, run the manual sync above. - Invoke with
/<skill-name>in Claude Code.
To prevent bad commits, we use Husky Git hooks.
yarn install installs the hooks through the postinstall script (Yarn 4 does
not run prepare). To reinstall them manually, run yarn postinstall.
The pre-commit hook hides unstaged edits while running ESLint and sorting the
staged translation files, then restores those edits after the tasks finish.
Commitlint rules are defined in the commitlint config.