- Screenshots & What
- Who & Why
- How - AI-Assisted Coding
- How - Setup, Run, Tests
- How - Project Creation
- Issues and Next TODOs
- Dev Docs/Guides
- Next Steps
- Potential & Known Issues
- License
Last updated: October 31, 2024
Deployment and video tutorial coming soon.
- Emotion Tracking: Log tab provides a calendar date picker with a custom form to track emotions through the various periods of the day. Track tab provides a table to reflect through past entries.
- Web App: A pet project in Ruby on Rails (RoR), ReactJS, MUI, and MUI X.
- Keyboard Navigation: Supports keyboard tab/shift-tab traversal, backspace/delete, and enter key functionality.
- Languages
- Ruby
- JavaScript
- SQL
- Frameworks
- Ruby on Rails
- React
- Redux
- Competencies
- OAuth 2.0 Authentication: Doorkeeper, Devise
- Faker for demo data population
- RESTful API Design
- Database Management
- Containerization
- Front-end State Management
- Environment Configuration
- Bundling and Asset Management
My name is Saad Shakil, I'm a Software Engineer currently located in Ottawa, ON. See the links below for my career bio, resume, and LinkedIn.
I started this in March 2022, paused while I was in grad school, and resumed as of summer 2024.
- Skill Maintenance & Demonstration: I started this a couple of years ago as a means to keep my coding skills alive upon taking a break from full-time work and pursuing graduate studies.
- Re-familiarization: Upon my graduation with a Master's in Engineering, Management (similar to an MBA) in June 2024, I resumed working on this part-time to refamiliarize myself with full-stack web application development through the MVP framework.
- Enjoyment: Also, I just find coding enjoyable, especially more so now with AI making it easier and more effective in some ways!
Later in the project, I experimented with the usage of:
- ChatGPT Plus
- JetBrains's AI Assistant
- CodeGPT plugin in JetBrains IDEs (including RubyMine, WebStorm, and PyCharm that I use)
- the Shell GPT plugin on iTerm2 with Zsh
- Co-Pilot
- Gemini Advanced
I found myself using the MacOS native ChatGPT app the most due to the ability to resume particular conversations with most accurate context enrichment (even though it has cross-session memory). The AI Assistant was also fairly good as it provided great commit messages and offered code changes that could be incorporated more directly within the IDEs.
I've learned a few things along the way about how to effectively use AI in aiding development of this app along with doing data-transormation heavy coding with R for the Data Science course I took, along with my experience using AI effectively and ethically for several other courses (todo: blog article[s]). For example, when repeated prompts are unable to achieve a desired result, including "try a different approach" often gets it to backtrack and get it right.
As it's a passion pet project for practicing coding, I didn't mind letting ChatGPT (Plus) have full knowledge of my code. For business use, I would only use an enterprise account which wouldn't be training their models, with maybe a system hook to scrub buffers to ensure copy-paste doesn't accidently transfer sensitive stuff (todo: experiment with this).
This assumes you can use MacOS package manager brew
on the CLI to install postgresql
and git
, update RubyGems(gem
) to install bundler, Ruby on Rails, and npm
to install MUI, among other libraries.
git clone [email protected]:sshakil/emotion-tracker.git
cd emotion-tracker
As it's an RoR project which typically starts from the Model layer in the Model-View-Controller (MVP) approach and goes up, let's setup the DB first.
See also: schema.md schema.md
As system daemon
brew services start postgresql@15
Or, manually
pg_ctl -D /usr/local/var/postgres start
Create user 'demo' and grants it all create table privileges.
Create DB User
psql -d postgres <<EOF
CREATE USER demo WITH PASSWORD 'P@ssword!1';
ALTER USER demo CREATEDB;
EOF
This creates the development and test databases.
Don't really need the first line, but switching from test
, in case.
bin/rails db:environment:set RAILS_ENV=development
db:create
The seed
task sets up initial user, periods, and OAuth tables.
The custom task populate
sits in lib/tasks
.
Currently, it imports 472 unique emotions/states.
rails db:migrate
rails db:seed
rails db:populate
or, all together when resetting:
rails db:drop && rails db:create && rails db:migrate && rails db:seed && rails db:populate
rails db:drop
psql -U admin -d postgres -c "DROP ROLE IF EXISTS demo;"
psql -U demo -d postgres
psql -U demo -d emotion_tracker
psql -U demo -d emotion_tracker_test
\l
\q
rails --tasks | grep db
Create DBs - this won't create tables and subsequent rails db:create
won't either, unless forced.
createdb emotion_tracker; createdb emotion_tracker_test
Explicit Permission Grants for Primary and Test DBs
psql -d postgres <<EOF
GRANT ALL PRIVILEGES ON DATABASE emotion_tracker TO demo;
GRANT ALL PRIVILEGES ON SCHEMA public TO demo;
ALTER SCHEMA public OWNER TO demo;
ALTER USER demo CREATEDB;
GRANT CREATE ON SCHEMA public TO demo;
ALTER DATABASE emotion_tracker OWNER TO demo;
EOF
psql -d emotion_tracker_test <<EOF
GRANT ALL PRIVILEGES ON DATABASE emotion_tracker_test TO demo;
ALTER DATABASE emotion_tracker_test OWNER TO demo;
EOF
These should cover everything explicitly if needed:
createdb emotion_tracker
createdb emotion_tracker_test
psql -d emotion_tracker <<EOF
CREATE USER demo WITH PASSWORD 'P@ssword!1';
ALTER USER demo CREATEDB;
ALTER DATABASE emotion_tracker OWNER TO demo;
ALTER DATABASE emotion_tracker_test OWNER TO demo;
ALTER SCHEMA public OWNER TO demo;
EOF
Showing through ...
next to "No databases selected" and selecting the DBs.
Showing the schemas, ...
next to "No schemas selected`:
Install Javascript libraries
npm install
Install Gems
bundle install
For typical dev flows.
rails s -p 3000
Optional env-var to disable OAUTH flow for a backend that doesn't yet have OAuth implemented
ENABLE_OAUTH
Use an incognito window to launch the app, to avoid cookie caching issues, which will receive 401s and present an app without data
npm run watch
Good to run using this to check everything before deploying to cloud.
Run docker:
docker compose up
or upon changes:
docker compose up --build
TODO: check if all the currently non-commented commands in this script are actually needed.
Script to create and populate the db: init-db.sh
docker compose --profile init-db up init_db
Currently, upon init_db
, need to get the generated OAuth App UID manually, set on front-end, and rebuild.
docker ps
docker exec -it <id for postgres service>
SELECT uid FROM oauth_applications;
exit
exit
docker compose up --build
TODO: expose this on backend through public controller then either fetch on every front-end call or fetch and set then reuse
[done: through fetching App UID from backend]
Visit: http://127.0.0.1:3000/
See Database Setup.
bin/rails db:environment:set RAILS_ENV=test
RAILS_ENV=test rails db:drop && RAILS_ENV=test rails db:create && RAILS_ENV=test rails db:migrate && RAILS_ENV=test rails:db:seed
Ensure the correct URL and PORT (3001):
RAILS_ENV=test rails console
Loading test environment (Rails 7.0.4.2)
irb(main):001:0> Doorkeeper::Application.first&.redirect_uri
Doorkeeper::Application Load (1.2ms) SELECT "oauth_applications".* FROM "oauth_applications" ORDER BY "oauth_applications"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> "http://localhost:3001/oauth/callback"
Needed for running specs.
brew install chromedriver
rspec
This is helpful, in config/environments/test.rb
:
Rails.application.configure do
...
Rails.logger = Logger.new(STDOUT)
config.log_level = :debug
Started with Yarn and SQLite then switched to npm and PostgreSQL later. This is just some of the how. I may add more granular details, for my own records as well, from my CLI history.
https://www.freecodecamp.org/news/how-to-create-a-rails-project-with-a-react-and-redux-front-end-8b01e17a1db/
brew install node
npx create-react-app my-app --template typescript
cd emotion-tracker-front
git branch -M main
echo "\n.idea" >> .gitignore
git add .
git commit -m "init + gitignore"
git remote add origin [email protected]:sshakil/emotion-tracker-front-end.git
git push -u origin main
yarn add react_ujs
yarn add react-dom
yarn add react
https://gorails.com/forum/error-in-chunk-application-entry-js-name-contenthash-js-cannot-use-chunkhash-or-contenthash-for-chunk-in
config/webpack/development.js
add:
const config = environment.toWebpackConfig();
config.output.filename = "js/[name]-[hash].js
# diverged here with ChatGPT here
Formatted date conversion issue
return (
<StaticDatePicker
orientation="portrait"
openTo="day"
value={ convertDateStringToDate(selectedDate) }
onChange={ (newSelectedDate) => {
// todo - these strips timezone info, which will be added back later
// const date = newValue.toISOString().split('T')[0] - this one has a day ahead issue
// const formattedDate = newSelectedDate.toLocaleDateString()
// backend needs format: "2022-10-01" (oct 1); front with toLocaleDateString() gives mm/dd/yyyy
// this converts it to needed format
// https://stackoverflow.com/questions/23593052/format-javascript-date-as-yyyy-mm-dd
// should be done on server side?
const date = convertToYYYYMMDD(newSelectedDate)
// console.log("StaticDatePicker - onChange: newSelectedDate, formattedDate: ", newSelectedDate, formattedDate)
console.log("onChange: ", date)
dispatch(fetchDayIfNotInStore(date))
dispatch(setSelectedDate(date))
}
}
renderInput={ (params) => <TextField { ...params } /> }
/>
);
Emotion/Entry cards popping issue
[Fixed] Newly entered entries not showing for newly selected date until refresh
Focus not on TextField upon using mouse to delete card
TextField jumps forward and back
Hot reload through
[switched to esbuild, Nov 24, 2024]
HotModuleReplacementPlugin
and ReactRefreshWebpackPlugin
currently not working through npm start
and the script in package.json
. Intuitively, this may be due to the nature of EmotionTracker.js
in combination with component HMR being too brittle.
App layout starts in /emotion-tracker/app/javascript/components/App.js
.
App
references Dashboard
, which is a Grid
containing 2 Grids containing Calendar
and EmotionTracker
.
EmotionTracker
is rendered through renderDayForm
, which renders a Stack
of Card
's through renderPeriod
.
Each Card
contains CardContent
which wraps:
Typography
to display period name,TextField
to input emotion/affectIconButton
to allow using the mouse to add the value
TODO: expand
Entries
is what connects a day_period
with an emotion
TODO: expand
Started switching to PG on 19/08/2024.
TODO: Expand
The following items in this order would isolate all the required changes on the infrastructure side to more or less one go.
- [OAuth2 - done, UAM - todo] Identity/User Account Management (Authentication and Authorization)
- Testing (including pen/sec), Continuous Integration, Continuous Deployment
- [Experiment - done, Implementation - todo] Data Analytics using AI
- [done]
Containerization& Deployment to Cloud (AWS)
However, since I'd like to demonstrate the app ASAP, I'll be proceeding with #4, then 1, 3, and 2.
Though I didn't proceed with TDD/BDD, it's something I would prefer to do at orgs for greenfield as well as existing projects.
- currently any user can access all entries
- session CSRF token reset upon
DELETE /users/sign_out
- current workaround: disable CSRF check for DELETE on that route
- workaround and better solution: https://stackoverflow.com/questions/11845500/rails-devise-authentication-csrf-issue
- current workaround: disable CSRF check for DELETE on that route
package.json
: On Windows and Linux, directly settingNODE_ENV=test
in the command may not work. Use thecross-env
package.package.json
: Tree Shaking might remove CSS from build output for production, as per this: https://stackoverflow.com/questions/61198311/webpack-not-acting-on-sideeffects-for-css-files- currently
"sideEffects": ["*.css"],
is added in anticipation of this
- currently
© 2024 Saad Shakil. All rights reserved.
This project is licensed under a private license for educational purposes and the author's skill-set evaluation for job or contract applications only. You may use, modify, and learn from the code provided here solely for your personal educational use or the evaluation of the author's skill-set during a job or contract application process. Redistribution, commercial use, or privately sharing of this code for any other purpose than identified or sharing it publicly in any form for any purpose is strictly prohibited without explicit permission from the author.
- Skill-set Evaluation: The code may be used to evaluate the author's skill-set during job or contract application processes.
- Educational Use: The code may be used for private learning and educational purposes. It cannot be used for commercial purposes or shared with others.
- Attribution: If referencing the code within private only for educational use or in evaluations (e.g., in private communications during a job/contract application), you must give appropriate credit to the original author, Saad Shakil.
- Non-Releasable: The code cannot be released or distributed privately for any other purpose than listed or publicly for any purpose in any form without explicit permission.
- Non-Harm/Indemnity: By using this code for private educational purposes or in skill-set evaluations, you agree to indemnify and hold harmless the author, Saad Shakil, from any claims, damages, or liabilities arising from its use. This includes, but is not limited to, any issues related to the functionality, reliability, or performance of the code in your own or third-party environments.
For any questions or permissions, please contact Saad Shakil.