Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
10 KiB
10 KiB
Development Guide
This guide covers development workflows, best practices, and common tasks when working with the PSA platform.
Development Environment Setup
Prerequisites
- Docker Engine 24.0.0+
- Docker Compose v2.20.0+
- Node.js 18+
- Git
- VS Code (recommended)
Initial Setup
- Clone and setup:
git clone https://github.com/your-org/alga-psa.git
cd alga-psa
cp .env.example .env.development
- Create development secrets:
mkdir -p secrets
# Create development secrets with dummy values
echo 'dev-password' > secrets/db_password_server
echo 'dev-password' > secrets/db_password_hocuspocus
# ... create other required secrets
chmod 600 secrets/*
- Start development environment:
# For Community Edition
docker compose -f docker-compose.base.yaml -f docker-compose.ce.yaml up
# For Enterprise Edition
docker compose -f docker-compose.base.yaml -f docker-compose.ee.yaml up
Development Workflow
1. Code Organization
alga-psa/
├── server/ # Next.js application server
│ ├── src/ # Source code (App Router pages, components, lib)
│ └── migrations/ # Database migrations (CE)
├── packages/ # Shared @alga-psa/* packages (~50 packages)
│ ├── build-tools/ # Shared tsup build preset
│ └── <domain>/ # Domain packages (billing, clients, tickets, etc.)
├── ee/ # Enterprise Edition (server, packages, migrations)
├── shared/ # Legacy shared libraries
├── hocuspocus/ # Real-time collaboration server
├── services/
│ └── workflow-worker/ # Workflow processing service
└── sdk/ # Extension SDK & samples
Package Build System
Domain logic lives in @alga-psa/* packages under packages/. Some are pre-built (compiled by tsup to dist/ before dev/build), others are source-transpiled (compiled by Next.js from src/).
npm run devautomatically builds all pre-built packages vianpx nx build-deps serverbefore starting the dev server- Nx caches build outputs — subsequent runs are near-instant
- See Package Build System for full details on which packages use which mode and how to flip a package
2. Branch Strategy
main: Production-ready codedevelop: Integration branchfeature/*: New featuresfix/*: Bug fixesrelease/*: Release preparation
3. Development Cycle
- Create feature branch:
git checkout -b feature/your-feature
- Start development environment:
docker compose -f docker-compose.base.yaml -f docker-compose.ce.yaml up
- Make changes and test
- Commit changes:
git add .
git commit -m "feat: description"
- Push and create PR:
git push origin feature/your-feature
Common Development Tasks
Database Migrations
- Create new migration:
cd server
npm run migrate:make your_migration_name
- Run migrations:
npm run migrate:latest
- Rollback:
npm run migrate:rollback
Testing
- Run all tests:
npm test
- Run specific tests:
npm test -- path/to/test
- Watch mode:
npm test -- --watch
Working with Docker
- Rebuild specific service:
docker compose build server
- View logs:
docker compose logs -f [service]
- Restart service:
docker compose restart [service]
- Clean up:
docker compose down -v
Development Best Practices
1. Code Style
- Follow ESLint configuration
- Use TypeScript for type safety
- Follow existing patterns
- Document complex logic
- Write meaningful commit messages
2. Server Action Authentication
All server actions that need authentication and database access should use the withAuth wrapper:
import { withAuth, hasPermission } from '@alga-psa/auth';
import { createTenantKnex } from '@alga-psa/db';
export const myAction = withAuth(async (user, { tenant }, arg1: string): Promise<Result> => {
const { knex } = await createTenantKnex();
if (!await hasPermission(user, 'resource', 'action')) {
throw new Error('Permission denied');
}
return knex('table').where({ tenant }).select('*');
});
Key points:
withAuthhandles authentication and sets tenant context via AsyncLocalStorage- The wrapper provides typed
user(IUserWithRoles) and{ tenant }as first two arguments - Additional action arguments follow after the context
- Always check permissions using
hasPermission(user, resource, action)
3. Testing
- Write tests for new features
- Maintain test coverage
- Use meaningful test descriptions
- Test edge cases
- Mock external dependencies
4. Docker
- Keep images minimal
- Use multi-stage builds
- Don't store secrets in images
- Use proper cache busting
- Tag images appropriately
5. Security
- Never commit secrets
- Use environment variables
- Validate user input
- Follow OWASP guidelines
- Regular dependency updates
Debugging
1. Server Debugging
- Enable debug logs:
docker compose up -f docker-compose.base.yaml -f docker-compose.ce.yaml -e DEBUG=true
- Use VS Code debugger:
- Launch configuration provided
- Breakpoints supported
- Variable inspection
- Call stack tracking
2. Database Debugging
- Connect to database:
docker compose exec postgres psql -U psa_user psa_db
- View logs:
docker compose logs postgres
3. Event Bus and Redis Debugging
- Redis CLI:
docker compose exec redis redis-cli
- Monitor all Redis events:
docker compose exec redis redis-cli monitor
- Monitor event streams:
# Monitor all events
docker compose exec redis redis-cli psubscribe "alga-psa:event:*"
# Monitor specific event type
docker compose exec redis redis-cli psubscribe "alga-psa:event:TICKET_UPDATED"
- View event bus subscribers:
docker compose exec redis redis-cli pubsub channels "alga-psa:event:*"
- Debug event bus configuration:
# Check Redis connection
docker compose exec redis redis-cli ping
# View event bus channels
docker compose exec redis redis-cli pubsub channels
# Check channel subscribers
docker compose exec redis redis-cli pubsub numsub channel_name
Event Bus System
1. Configuration
The event bus system uses Redis for event streaming. Configure through environment variables:
# Redis Configuration
REDIS_URL=redis://localhost:6379
REDIS_PREFIX=alga-psa:
REDIS_EVENT_PREFIX=event:
REDIS_RECONNECT_RETRIES=10
REDIS_RECONNECT_INITIAL_DELAY=100
REDIS_RECONNECT_MAX_DELAY=3000
2. Working with Events
- Create new event types:
// In server/src/lib/eventBus/events.ts
export const EventTypeEnum = z.enum([
'YOUR_NEW_EVENT',
// ... other events
]);
export const YourEventPayloadSchema = BasePayloadSchema.extend({
// Define your event payload schema
// BasePayloadSchema already includes tenantId
});
// Add to EventPayloadSchemas
export const EventPayloadSchemas = {
YOUR_NEW_EVENT: YourEventPayloadSchema,
// ... other schemas
};
- Create event subscriber:
// In server/src/lib/eventBus/subscribers/yourSubscriber.ts
import { eventBus } from '../index';
import { YourEvent, EventType } from '../events';
async function handleYourEvent(event: YourEvent): Promise<void> {
const { tenantId } = event.payload;
// Handle the event
}
export async function registerYourSubscriber(): Promise<void> {
await eventBus.subscribe(
'YOUR_NEW_EVENT',
handleYourEvent
);
}
- Publish events:
import { eventBus } from 'lib/eventBus';
await eventBus.publish({
eventType: 'YOUR_NEW_EVENT',
payload: {
tenantId: 'tenant-id',
// Your event data
},
});
3. Testing Events
- Create event bus mocks:
// In your test file
jest.mock('lib/eventBus', () => ({
eventBus: {
publish: jest.fn(),
subscribe: jest.fn(),
},
}));
- Test event publishing:
test('should publish event', async () => {
const event = {
eventType: 'YOUR_NEW_EVENT',
payload: {
tenantId: 'test-tenant',
// ... other payload data
},
};
await yourFunction();
expect(eventBus.publish).toHaveBeenCalledWith(
expect.objectContaining(event)
);
});
- Test event handling:
test('should handle event', async () => {
const event = {
id: 'test-id',
eventType: 'YOUR_NEW_EVENT',
timestamp: new Date().toISOString(),
payload: {
tenantId: 'test-tenant',
// ... other payload data
},
};
await handleYourEvent(event);
// Assert expected behavior
});
Performance Optimization
1. Database
- Index frequently queried fields
- Optimize complex queries
- Regular VACUUM
- Monitor query performance
2. Application
- Use caching effectively
- Optimize API responses
- Implement pagination
- Profile memory usage
3. Docker
- Optimize image sizes
- Use volume mounts
- Configure resource limits
- Monitor container stats
Troubleshooting
Common Issues
-
Database Connection Issues
- Check credentials
- Verify host/port
- Check network connectivity
-
Redis Connection Issues
- Verify password
- Check persistence config
- Monitor memory usage
-
Build Issues
- Clear Docker cache
- Update dependencies
- Check Dockerfile syntax
Debug Commands
# Check service status
docker compose ps
# View service logs
docker compose logs [service]
# Check network
docker network inspect alga-psa_default
# Container shell access
docker compose exec [service] sh
Development Tools
Recommended VS Code Extensions
- Docker
- ESLint
- Prettier
- TypeScript
- GitLens
- REST Client
Useful Scripts
- Development setup:
./scripts/dev-setup.sh
- Test data generation:
./scripts/generate-test-data.sh
- Dependency updates:
./scripts/update-deps.sh