Stocks in the Future is a program with the mission of developing highly motivated middle school students who are eager to learn and dedicated to attending class through the use of incentives coupled with a financial literacy curriculum focused on investing that reinforces Math, Language Arts and Social Studies. Stocks in the Future pushes to educate, encourage, and empower the next generation of financially-literate individuals. This application is used by the students to manage their portfolios by trading and selling their stocks. It is also used by the teachers and administrator to manage the classrooms, enter student's grades, attendance, and post announcements.
If you have any questions about an issue, comment on the issue, open a new issue, or ask in the RubyForGood slack. Stocks-in-the-future has a #stocks-in-the-future channel in the Slack. Feel free to join the community!
To understand the project better, read the project documentation.
Then follow our contributing guide to get started.
- A ruby version manager such as rvm, rbenv or asdf
- Ruby 3.4.4 (Installed via ruby manager ^)
- PostgreSQL, if you're not using Docker.
- npm and yarn (
npm install -g yarn)
Go to the Easy Docker Scripts page for an easy way to set up this app, test this app, seed data, run RuboCop, and execute other routine tasks.
Create config/database.yml. A copy of config/database.yml.sample should be adequate.
Build and start the application with docker compose up. Once the application has successfully started, you should be able to visit it at http://localhost:3000/
Run commands in docker with the bin/dc helper script on macos or Linux.
$ bin/dc rails db:setup
$ bin/dc rails testOr by prefacing rails commands with docker compose run stocks.
$ docker compose run stocks rails db:setup
$ docker compose run stocks rails test- Run setup:
bin/setup - Run the Rails server locally:
bin/dev
It is strongly recommended to use Docker. See instructions above.
After running bin/rails db:setup, the database will automatically be seeded with three default users.
| Role | Username | Password |
|---|---|---|
| Teacher | Teacher | password |
| Student | Student | password |
| Admin | Admin | password |
Use the username and password to log in and test the application locally.
Access the app via localhost:3000
Password reset and account setup emails are sent through Devise using Rails Action Mailer. In staging and production, Action Mailer is configured to use Amazon SES SMTP in us-east-1.
The SES domain identity is sifonline.org. DKIM is verified with three CNAME records in GoDaddy DNS:
xqnfudzzscsqz2vbneqh75ojqwduiphb._domainkey.sifonline.org -> xqnfudzzscsqz2vbneqh75ojqwduiphb.dkim.amazonses.com
4zk3q7oy5kz7xubi2gxqkn2kpqglwgms._domainkey.sifonline.org -> 4zk3q7oy5kz7xubi2gxqkn2kpqglwgms.dkim.amazonses.com
qsq7nni46gdkvr6vu7gn6cm4rexzo22u._domainkey.sifonline.org -> qsq7nni46gdkvr6vu7gn6cm4rexzo22u.dkim.amazonses.com
The SES SMTP credentials are stored in AWS Secrets Manager:
stocks-in-the-future/ses-smtp
The app reads these runtime environment variables from /etc/stocks/env on each Lightsail instance:
APP_HOST
MAILER_SENDER
SES_SMTP_ADDRESS
SES_SMTP_PORT
SES_SMTP_USERNAME
SES_SMTP_PASSWORD
Expected values by environment:
production APP_HOST=app.sifonline.org
staging APP_HOST=staging.sifonline.org
MAILER_SENDER=no-reply@sifonline.org
SES_SMTP_ADDRESS=email-smtp.us-east-1.amazonaws.com
SES_SMTP_PORT=587
SES may still be sandboxed in a new AWS account or region. If ProductionAccessEnabled is false, SES can only send to verified recipient email addresses even if the sifonline.org sending domain is verified.
Check SES status:
AWS_PROFILE=713141626029_AdministratorAccess AWS_REGION=us-east-1 aws sesv2 get-email-identity --email-identity sifonline.org
AWS_PROFILE=713141626029_AdministratorAccess AWS_REGION=us-east-1 aws sesv2 get-accountThe Lightsail instances are registered with AWS Systems Manager as hybrid managed instances so routine ops do not require SSH keys.
Current managed instances:
production_web -> mi-059a7bcb37754c44d
staging_web -> mi-0c65ce3a1a596c81c
Check SSM connectivity:
AWS_PROFILE=713141626029_AdministratorAccess AWS_REGION=us-east-1 aws ssm describe-instance-informationRun a safe health check through SSM:
AWS_PROFILE=713141626029_AdministratorAccess AWS_REGION=us-east-1 aws ssm send-command \
--instance-ids mi-059a7bcb37754c44d mi-0c65ce3a1a596c81c \
--document-name AWS-RunShellScript \
--parameters '{"commands":["systemctl is-active stocks && grep -E \"^(APP_HOST|MAILER_SENDER|SES_SMTP_ADDRESS|SES_SMTP_PORT|SES_SMTP_USERNAME|SES_SMTP_PASSWORD)=\" /etc/stocks/env | sed -E \"s/=.*/=present/\""]}'Do not print SES_SMTP_PASSWORD or other secrets in terminal output. Check for key presence only.
If reset password emails do not send:
- Confirm the deployed code includes SES Action Mailer configuration in
config/environments/production.rborconfig/environments/staging.rb. - Confirm the app was restarted after updating
/etc/stocks/env:sudo systemctl restart stocks. - Confirm required env keys exist on the server using SSM. Do not print secret values.
- Confirm SES identity status is
SUCCESSand DKIM status isSUCCESS. - Confirm SES production access is enabled, or verify the recipient email address while SES is still sandboxed.
- Check recent app logs:
AWS_PROFILE=713141626029_AdministratorAccess AWS_REGION=us-east-1 aws ssm send-command \
--instance-ids mi-059a7bcb37754c44d \
--document-name AWS-RunShellScript \
--parameters '{"commands":["sudo journalctl -u stocks -n 200 --no-pager"]}'If SSM stops working, first confirm the instance is listed as Online in aws ssm describe-instance-information. If it is missing or offline after a rebuild, install/register the SSM agent again with a new SSM hybrid activation, then enable the agent service so it persists across reboot.
The application hostname is app.sifonline.org. It should point to the Terraform-managed production Lightsail load balancer:
stocks-production-lb
1c0d863aa670cdbc48e7167de9d300ef-1607315586.us-east-1.elb.amazonaws.com
Staging uses:
staging-lb
d74e239060df7f70047c7878e32ed0c8-1040760270.us-east-1.elb.amazonaws.com
If the app returns an AWS ELB 503, check whether DNS points to an old load balancer or whether the target instance is detached/unhealthy. If HTTPS fails after an HTTP redirect, check that the Lightsail load balancer has a valid attached TLS certificate and exposes port 443.