New Customer Onboarding (Package-Based Architecture)
This guide outlines the streamlined process for onboarding new enterprise customers using the package-based architecture, replacing the legacy fork-based approach.
Prerequisites
- Decisions:
- Domain name (
SERVER_DOMAIN
,PREVIEW_DOMAIN
, andHOSTED_ZONE
if DNS zone is different thanSERVER_DOMAIN
) (Customer) - Will AWS be managing the service certificates? (Recommended) (Customer)
- Allocate a VPC to run the service (one per AWS account), and set any security groups for reaching that VPC (Customer)
- If service can't be on internet, SST changes may be required (Bike4Mind)
- Support email address (Customer)
- Mail from address (Customer)
- Where to run MongoDB or DocumentDB (Customer)
- Domain name (
Package Setup (Replaces Fork Process)
-
Access to Private NPM Registry (Coordinated)
- Bike4Mind provides NPM organization access credentials (Bike4Mind)
- Customer configures NPM registry access:
npm config set @bike4mind:registry https://registry.npmjs.org
(Customer) - Customer authenticates:
npm login --scope=@bike4mind
(Customer)
-
Create Customer Repository (Customer)
- Create new repository within customer org:
customer-bike4mind
(Customer) - Initialize with package.json containing:
{
"name": "customer-bike4mind",
"version": "1.0.0",
"private": true,
"dependencies": {
"@bike4mind/core": "^1.0.0",
"@bike4mind/client": "^1.0.0"
}
} - Run
npm install
to fetch packages (Customer) - Commit initial package setup (Customer)
- Create new repository within customer org:
AWS Infrastructure Setup
-
Create new AWS account, configure services (Customer)
Create account according to instructions in https://v2.sst.dev/setting-up-aws, skipping the last section "Configure SST"
Once accounts are created, be sure to logout and log back in under the proper sub-account/organization for resource creation
- Route53 (sub-)zone, based on
SERVER_DOMAIN
andHOSTED_ZONE
- Create VPC for services, store id (vpc-1234adfe) in
$VPC_ID
- note: cannot use the default public VPCs in the account- Select 'VPC and more', using defaults except:
- Ensure IP space is not in conflict if needing to communicate with other networks
- Enable NAT gateway to corporate standards (in 1 AZ vs the recommended 1 per AZ)
- SES, based on domain name selection
- Get Started, enter email address and domain
- Verify Sending Domain, updating records in DNS (seems to be manual, even when on Route53?)
- Once verified, do Request Production Access
- Then SMTP Settings > Create SMTP Credentials
- Capture credentials to
MAIL_USERNAME
,MAIL_PASSWORD
- Create an ECR called
bike4mind/subscriber-fanout
- MongoDB or DocumentDB setup:
- Instance-based cluster
- Select sizing per organization need
- Specify a password (don't use secrets manager)
- Select other options as desired
- Note: Bike4Mind packages support both MongoDB and DocumentDB
- Bedrock: Enable relevant (or all) models in us-east-1 (not your local AZ!)
- Quotas:
- Ensure Lambda's 'Max Concurrent Execution' quota is at least the default (1000) - this is an account-wide quota that may only be available in US-EAST-1 (Customer)
-
AWS Roles Per Account
(available only in us-east-1): set to 3000, especially in development accounts where we'll run numerous stages (Customer)
- Route53 (sub-)zone, based on
-
Create MongoDB/DocumentDB service (Customer)
- If using DocumentDB, see steps in AWS section above
- If using external MongoDB, provision according to organization standards
- Get connection string, store in
MONGODB_URI
secret - Connection string should support both MongoDB and DocumentDB protocols
Deployment Configuration
-
Do initial SST bootstrap:
npx sst bootstrap --profile $aws_credentials_profile
(Customer) -
Create new Seed account (Customer)
-
Add a new App (Customer)
- Link the customer repository containing the Bike4Mind packages
- Add a service:
/
of type SST, service name bike4mind, click Add Service - "Help me create an IAM role" for both dev and prod, > Create an IAM Role using CloudFormation
- Ensure the right AZ is selected
- Check the Acknowledgment under Capabilities, then Create Stack
-
Configure app settings (Customer)
- Go to
dev
env, click Show Env Variables, enter variables as per below-
ECR_CACHE_REPO
: Docker repo for ECR, e.g.$account_id.dkr.ecr.$aws_region.amazonaws.com/bike4mind/subscriber-fanout
-
SERVER_DOMAIN
: The domain name suffix that will run the app, e.g. app.$SERVER_DOMAIN
-
PREVIEW_DOMAIN
: The domain name suffix to use for preview builds in development; we'll prependapp.pr$number.
to this domain when making PR/preview branches -
HOSTED_ZONE
: The DNS zone (in Route53) that contains$SERVER_DOMAIN
, if not the same -
APP_CERT_ARN
: required if AWS isn't generating the certificates on its own -
VPC_ID
: A VPC to run certain services - if none given, it will create one if needed. Note that this does not affect whether the application load balancers are public-facing -
FAB_FILES_BUCKET_NAME
: If specified, the bucket that will contain Knowledge Files. If not specified, application will create its own (recommended) -
GENERATED_IMAGES_BUCKET_NAME
: If not specified, application will create its own (recommended) -
APP_FILES_BUCKET_NAME
: If not specified, application will create its own (recommended) -
ENABLE_BUCKET_VERSIONING
: true/false -
ENABLE_WARMING
: true/false - Automatically set in Seed:
SEED_APP_NAME
: the installation name, something customer-specific is recommended - Automatically set in Seed:
SEED_STAGE_NAME
:production
anddev
are meaningful - Automatically set in Seed: CI: true for CI environments
-
- Go to
-
Secrets Configuration
- Create secrets for each stage (Customer)
-
MONGODB_URI
: from MongoDB/DocumentDB service, substituting%stage%
where needed- Note: Connection string format supports both MongoDB and DocumentDB
- Secrets
-
SESSION_SECRET
: arbitrary -
JWT_SECRET
: arbitrary
-
- Google login
-
GOOGLE_CLIENT_ID
-
GOOGLE_CLIENT_SECRET
-
- GitHub login
-
GITHUB_CLIENT_ID
-
GITHUB_CLIENT_SECRET
-
- Okta organization login
-
OKTA_AUDIENCE
-
OKTA_CLIENT_ID
-
OKTA_CLIENT_SECRET
-
-
PDFJS_EXPRESS_VIEWER_KEY
-
DEFAULT_THEME
- Stripe
-
STRIPE_SECRET_KEY
-
STRIPE_PUBLISHABLE_KEY
-
STRIPE_WEBHOOK_SECRET
-
- Email-related
-
SUPPORT_EMAIL
-
MAIL_FROM
-
MAIL_HOST
-
MAIL_PORT
-
MAIL_USERNAME
-
MAIL_PASSWORD
-
- SalesForce (if applicable)
-
SF_CONSUMER_KEY
-
SF_CONSUMER_SECRET
-
SF_USERNAME
-
SF_PASSWORD
-
SF_SECURITY_TOKEN
-
SF_INSTANCE
-
-
Initial Build and Deploy
-
Local SST build to update zone list (Customer)
-
SERVER_DOMAIN=$server_domain HOSTED_ZONE=$hosted_zone VPC_ID=$vpc_id pnpm sst build --profile $aws_profile --region $aws_region --stage dev
- Review and commit any necessary cdk.context.json changes
-
-
Deploy from Seed (Customer)
- Push configuration to repository
- Trigger deployment in Seed
- Monitor deployment progress
- Verify application is accessible at configured domain
Package Updates
With the package-based architecture, updates are streamlined:
- Receive update notification from Bike4Mind
- Update package versions in package.json:
{
"dependencies": {
"@bike4mind/core": "^1.1.0",
"@bike4mind/client": "^1.1.0"
}
} - Run
npm install
to fetch updates - Test in development environment
- Deploy through Seed CI/CD pipeline
Advantages Over Fork-Based Approach
- No submodule management: Eliminates daily submodule pointer updates
- Simplified updates: Standard NPM package versioning
- Better isolation: Clear separation between customer code and Bike4Mind packages
- Easier rollbacks: Use NPM version pinning for stability
- Cleaner repository: Customer repository contains only customizations
- Database flexibility: Native support for both MongoDB and DocumentDB
Support and Maintenance
- Package updates are published to the private NPM registry
- Version compatibility is maintained through semantic versioning
- Breaking changes are communicated in advance
- Customer customizations remain isolated in their repository
- Full source code transparency maintained through package access