EcoWorld Academy Platform — Phase 1
Viroway Ltd | EcoWorld Educational Arm
Stack: Webflow + AWS (Cognito · Lambda · DynamoDB · API Gateway · S3) + HubSpot CRM
Three things to do before the first deployment
In HubSpot: Create the Private App, add the 8 custom Company properties and 4 Contact properties, and set ecoworld_company_code on each client company record
In AWS: aws secretsmanager create-secret --name ecoworld/hubspot-token ... with the HubSpot token
Update CONFIG in ecoworld-academy.js with the CDK deploy outputs, then paste into Webflow
One important note on Viroway vs. EcoWorld: the platform as built uses ecoworld.ai as the origin — if we later want it under a Viroway domain or a white-label subdomain per client, just change WEBFLOW_ORIGIN in the CDK deploy command. The architecture supports it natively.
What this repository contains
| Folder | Contents |
|---|---|
lambdas/post-confirmation | Cognito trigger — fires when a user confirms registration. Links learner to HubSpot company. |
lambdas/hubspot-sync | HubSpot sync — creates/updates contact in HubSpot, associates with company record. |
lambdas/save-answer | Saves a workbook exercise answer to DynamoDB |
lambdas/get-progress | Returns a user's progress across all modules |
lambdas/submit-questionnaire | Saves supplier questionnaire responses |
lambdas/risk-score | Calculates and returns supplier risk tier |
lambdas/dashboard | Company admin dashboard data aggregation |
frontend/ | Webflow custom code snippets (JS embeds) |
infra/ | AWS CDK infrastructure as code |
docs/ | Architecture decisions, API reference, deployment guide |
Quick start
Prerequisites
- AWS CLI configured with the Viroway AWS account
- Node.js 20+
- HubSpot Private App token (store in AWS Secrets Manager)
Deploy infrastructure
cd infra
npm install
npx cdk deploy --all
Deploy all Lambdas
./deploy-all.sh
Add Webflow custom code
Copy each file from frontend/ into the Webflow site's Custom Code section (Site Settings → Custom Code).
Environment variables (set in AWS Secrets Manager)
| Secret name | Value |
|---|---|
ecoworld/hubspot-token | HubSpot Private App access token |
ecoworld/hubspot-portal-id | The HubSpot portal ID |
HubSpot setup required
- In HubSpot: Settings → Integrations → Private Apps → Create Private App
- Name: "EcoWorld Academy Sync"
- Required scopes:
crm.objects.contacts.read,crm.objects.contacts.write,crm.objects.companies.read,crm.schemas.contacts.read - Copy the access token → store in AWS Secrets Manager as
ecoworld/hubspot-token - Add custom company properties in HubSpot:
ecoworld_seats_purchased(Number)ecoworld_course_assigned(Single-line text)ecoworld_cohort_start(Date)ecoworld_enrolment_status(Dropdown: Pending / Active / Completed)
- Add custom contact properties:
ecoworld_user_id(Single-line text) — Cognito subecoworld_completion_pct(Number)ecoworld_certificate_issued(Date)ecoworld_last_active(Date)
Data model
HubSpot (CRM — company + account data)
Company ──────── contacts (HR sponsor, account owner)
└── custom: seats, course, cohort, status
AWS Cognito (auth — individual learners)
User Pool
└── user attributes: email, name, custom:hubspot_company_id,
custom:company_name, custom:company_code
DynamoDB Tables
ecoworld-answers PK: userId SK: moduleId#exerciseId
ecoworld-progress PK: userId SK: moduleId
ecoworld-completions PK: companyId SK: userId
ecoworld-suppliers PK: companyId SK: supplierId
ecoworld-risk-scores PK: companyId SK: supplierId