This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
SFA Backoffice Administration Web Application - A full-stack TypeScript/Vue.js application for managing Student Financial Assistance (SFA) applications, funding requests, assessments, and student records. The application integrates with Auth0/YNet authentication and uses Microsoft SQL Server.
/src/api: Node.js/TypeScript Express API backend/src/web: Vue.js 2 + Vuetify frontend/db: Database schema, migrations, and SQL scripts
The API follows a layered architecture:
- Routes (
routes/): Express route handlers organized by domainroutes/admin/: Administrative endpoints (reference data, applications, assessments)routes/portal/: Student portal-facing endpointsroutes/auth.ts: Authentication configuration and middleware
- Controllers (
controllers/): Request/response handling logic - Services (
services/): Business logic layer - Repositories (
repositories/): Data access layer using Knex query builder - Models (
models/): TypeScript data models and types - Serializers (
serializers/): Transform data for API responses - Middleware (
middleware/): Authentication, authorization, validation
- Uses Knex.js query builder with MS SQL Server
- Database client (
db/db-client.ts) configured with:- Automatic camelCase/snake_case transformation (camelCase in code, snake_case in DB)
- Schema-aware proxy that automatically applies
defaultSchemato all queries - Non-standard column name handling via
NON_STANDARD_COLUMN_NAMES_TRANSFORMS
- Path aliases:
@/maps to the API root directory (configured via tsconfig.json and tsconfig-paths)
Dual authentication system:
- Auth0/OpenID Connect: Primary authentication via
express-openid-connect - JWT: Token-based auth via
express-jwtwith JWKS validation - Middleware:
RequireActivemiddleware checks user is active in database - Routes under
/api/v2/adminand/api/v2/referencerequire authentication - Portal routes (
/api/portal) may have different auth requirements
Vue.js 2 application with modular structure:
- Router (
router/): Vue Router with nested routes and auth guards - Store (
store/): Vuex state management with domain-specific modules - Modules (
modules/): Feature modules containing components, routes, stores, and API clients- Each module typically has:
router.js,store.js, API service files - Examples: student, institution, application-type, funding-group, etc.
- Each module typically has:
- Components (
components/): Reusable UI components organized by feature - Views (
views/): Top-level page components - API (
api/): HTTP client wrappers for backend communication
- Vuetify UI component library
- Module-based organization: each domain area (student, application, institution) has its own subdirectory
- API calls handled via dedicated service files (e.g.,
assessments-api.js) - HTTP client configured in
api/http-client.js
- MS SQL Server 2019 (via Docker in development)
- Schema managed via:
- SQL scripts in
/db:2_create_objects.sql,3_populate.sql,4_functions.sql - Knex migrations in
/src/api/data/migrations - Migration endpoints:
/migrate/up,/migrate/down,/migrate/latest
- SQL scripts in
- Default schema: configurable via
DB_DEFAULT_SCHEMAenv var (typicallysfa)
# 1. Create database password file
cp db/sapassword.env.sample db/sapassword.env
# 2. Start Docker services (database, S3, email, converter)
docker compose -f docker-compose.development.yaml up -d
# Or with dev helper:
dev up
# 3. Restore database backup (first time only)
# Place backup at /db/backups/sfa.bak, then:
dev up db
# Or: docker compose -f docker-compose.development.yaml up db
# 4. Configure Minio S3 (first time only)
# Visit http://localhost:9090
# Create bucket named "documents"
# Create access key and update API .env file
# 5. Setup API environment
cd src/api
cp .env.sample .env.development
# Update DB_PASS to match MSSQL_SA_PASSWORD from db/sapassword.env
# Configure other environment variables (Auth0, S3 credentials, etc.)
# 6. Setup and start web frontend
cd src/web
npm install
npm run start
# Frontend runs at http://localhost:8080# Start all services (DB, S3, Email, API) via Docker
dev up
# Or: docker compose -f docker-compose.development.yaml up
# Start frontend (in separate terminal)
cd src/web
npm run start
# Access application at http://localhost:8080cd src/api
# Install dependencies
npm install
# Run API in development mode (with hot reload)
npm run start
# Run tests in watch mode
npm test
# Build TypeScript
npm run build
# Run TypeScript REPL console
npm run console
# Run database migrations
npm run migrate:latestcd src/web
# Install dependencies
npm install
# Start dev server (http://localhost:8080)
npm run start
# Build for production
npm run build:web
# Build for Docker (outputs to ../app/dist/web)
npm run build:docker
# Lint code
npm run lint# Access SQL console
dev sqlcmd
# Or: docker compose -f docker-compose.development.yaml exec db /opt/mssql-tools/bin/sqlcmd -U sa -s localhost -P Testing1122
# Connect to database container
docker compose -f docker-compose.development.yaml exec -it db bash
# Run migrations via API endpoints (when API is running)
# GET http://localhost:3000/migrate/up
# GET http://localhost:3000/migrate/down
# GET http://localhost:3000/migrate/latestThe bin/dev Ruby script provides shortcuts (requires Ruby via asdf):
dev build # Build all Docker services
dev up # Start all services and watch logs
dev up db # Start only database service
dev down # Stop all services
dev logs # Follow logs for all services
dev logs api # Follow logs for specific service
dev sh # Open shell in API container
dev npm <command> # Run npm command in API container
dev sqlcmd # Open SQL terminal
dev debug # Open debug console for API# 1. Create production config
cp ./src/api/.env.development ./src/api/.env.production
# 2. Update config:
# - Set DB_HOST=db
# - Set FRONTEND_URL=http://localhost:3000
# - Set AUTH_REDIRECT=http://localhost:3000/dashboard
# 3. Start development database
dev up db
# 4. Build and start production container
docker compose up --build
# Access at http://localhost:3000/dashboardNODE_ENV: development | test | productionAPI_PORT: API server port (default: 3000)FRONTEND_URL: Frontend URL for CORSAUTH_REDIRECT: Post-login redirect URLDB_NAME,DB_USER,DB_PASS,DB_HOST,DB_PORT: Database connectionDB_DEFAULT_SCHEMA: Default schema (typically "sfa")CLIENT_ID,ISSUER_BASE_URL,CLIENT_SECRET: Auth0 configurationAUTH0_DOMAIN,AUTH0_AUDIENCE: JWT validationMAIL_FROM,MAIL_HOST,MAIL_PORT: Email configurationSENTRY_DSN: Sentry error tracking (optional)
- Column naming: Use camelCase in TypeScript code; automatic conversion to snake_case for database
- Schema: All queries use default schema from
DB_DEFAULT_SCHEMAunless explicitly overridden - Special columns: Some non-standard names handled via
NON_STANDARD_COLUMN_NAMES_TRANSFORMS
/api/portal/*: Portal/student-facing endpoints/api/v2/admin/*: Admin endpoints (requires auth + active user)/api/v2/reference/*: Reference data endpoints (requires auth + active user)/migrate/*: Database migration endpoints/auth/login,/auth/logout: Authentication endpoints/_status: Health check endpoint
Each module in src/web/src/modules/ typically includes:
router.js: Route definitionsstore.js: Vuex store module*-api.js: API client functions- Components specific to that domain
- API:
@/*resolves tosrc/api/*(TypeScript paths) - Web:
@/*resolves tosrc/web/src/*(Vue.js alias)
- Database: http://localhost:1433 (MSSQL)
- Minio S3: http://localhost:9090 (web UI), http://localhost:9000 (API)
- MailSlurper: http://localhost:8081 (email preview)
- PDF Converter: http://localhost:5000
- Frontend Dev Server: http://localhost:8080
- API: http://localhost:3000
The production Dockerfile builds both frontend and backend into a single container:
- Builds Vue.js frontend
- Copies built files to API's dist/web directory
- API serves static frontend files via Express
- Single container serves both frontend and API
- Main branch:
test(notmainormaster) - Fork repository to contribute
- Sync with upstream before creating PR
- PRs target
ytgov/sfa-client:test - Ensure
docker-compose buildsucceeds before submitting PR