CLAUDE.md - app-portal
This file provides guidance to Claude Code when working with the app-portal Backstage application.
Prerequisites
# Install required tools
brew install node@20 direnv sops age
Quick Start
# Enter directory (auto-loads environment and decrypts secrets)
cd app-portal
direnv allow
# Install and start
yarn install
yarn start
Frontend: http://localhost:3000
Backend: http://localhost:7007
Secret Management
This project uses SOPS for secret encryption with SSH keys:
- Encrypted files:
.env.enc
- GitHub App credentialsgithub-app-key.pem.enc
- GitHub App private key
- Auto-decryption: Via direnv when entering directory
- SSH-based: Uses your existing SSH key from GitHub
Adding Team Members
# Get their SSH public key
ssh-add -L # They run this
# Add to .sops.yaml, then:
sops updatekeys .env.enc
sops updatekeys github-app-key.pem.enc
Development Commands
# Start development server
yarn start
yarn start:log # With timestamped logging (Unix/Linux/macOS only)
# Installation
yarn install
yarn install:log # With timestamped logging (Unix/Linux/macOS only)
# Build for production
yarn build:backend
yarn build:all
# Testing
yarn test
yarn test:all
yarn test:e2e
# Linting and formatting
yarn lint
yarn lint:all
yarn prettier:check
yarn fix
# Clean build artifacts
yarn clean
# Create new plugin
yarn new
Logging Scripts
The :log
variants capture timestamped output for debugging:
- Default location:
./logs/
- Custom:
BACKSTAGE_LOG_DIR=/path yarn start:log
- Platform: Unix/Linux/macOS only (uses shell-specific syntax)
Project Structure
app-portal/
├── packages/
│ ├── app/ # Frontend React application
│ │ ├── src/
│ │ │ ├── App.tsx # Main app component
│ │ │ └── components/ # UI components
│ │ └── package.json
│ └── backend/ # Backend Node.js services
│ ├── src/
│ │ ├── index.ts # Backend entry point
│ │ └── scaffolder/ # Custom scaffolder actions
│ │ ├── index.ts
│ │ └── generateId.ts
│ └── package.json
├── examples/ # Example data for development
│ ├── entities.yaml # Example catalog entities
│ ├── org.yaml # Example users/groups
│ └── template/ # Example template
├── app-config.yaml # Base configuration
├── app-config.production.yaml # Production overrides
├── app-config.local.yaml # Local overrides (gitignored)
├── .envrc # Direnv config (auto-loads secrets)
├── .sops.yaml # SOPS encryption config
└── backstage.json # Backstage version
Configuration
GitHub App Integration
The GitHub App provides:
- Repository discovery
- Template scaffolding
- Authentication
Credentials are stored encrypted in .env.enc
.
Catalog Providers
-
GitHub Organization Scanner
- Org:
open-service-portal
- Frequency: 30 minutes
- Org:
-
Template Discovery
- Pattern:
service-*-template
repositories - Auto-imports templates from GitHub
- Pattern:
Authentication
- Development: GitHub OAuth + Guest auth
- Production: GitHub OAuth only
Custom Features
Scaffolder Actions
Custom action for unique ID generation:
- Location:
packages/backend/src/scaffolder/generateId.ts
- Generates unique resource identifiers
Integrations
- GitHub (primary)
- Kubernetes (optional, configured in app-config.local.yaml)
- TechDocs (local builder)
Troubleshooting
Secrets not loading
# Check if SSH key is loaded
ssh-add -L
# If "The agent has no identities", add your SSH key:
ssh-add ~/.ssh/id_ed25519 # or ~/.ssh/id_rsa
# Manually test decryption
sops -d --input-type dotenv --output-type dotenv .env.enc
# Re-allow direnv
direnv allow
SSH key with passphrase
If using a passphrase-protected SSH key, you'll be prompted when entering the directory:
- Enter the passphrase once per terminal session
- Or add key to ssh-agent:
ssh-add ~/.ssh/id_ed25519
- Alternative: Use a dedicated key without passphrase for development
Build issues
# Clean and rebuild
yarn clean
yarn install
yarn build:backend
Port conflicts
Default ports:
- Frontend: 3000
- Backend: 7007
Change in app-config.yaml if needed.
Testing
# Unit tests
yarn test
# With coverage
yarn test:all
# E2E tests (requires running app)
yarn test:e2e
Deployment
See deploy-backstage repository for Kubernetes deployment.
Contributing
- Create feature branch from
main
- Make changes
- Run tests:
yarn test
- Run linter:
yarn lint
- Create PR with semantic commit message
Related Repositories
- portal-workspace - Parent workspace with documentation
- service-nodejs-template - Node.js service template
- deploy-backstage - Kubernetes deployment (coming soon)