{"id":16481757,"url":"https://github.com/richardd3ng/shelf-stability-system","last_synced_at":"2026-01-20T00:40:59.583Z","repository":{"id":218415784,"uuid":"745561651","full_name":"richardd3ng/Shelf-Stability-System","owner":"richardd3ng","description":"Duke ECE 458 Senior Design Project","archived":false,"fork":false,"pushed_at":"2024-05-01T23:04:00.000Z","size":1999,"stargazers_count":1,"open_issues_count":3,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T04:27:17.460Z","etag":null,"topics":["material-ui","nextjs","postgresql","prisma","react","sendgrid","swagger","vercel"],"latest_commit_sha":null,"homepage":"https://shelf-stability-system.colab.duke.edu","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/richardd3ng.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-19T15:52:58.000Z","updated_at":"2024-05-13T23:12:39.000Z","dependencies_parsed_at":"2024-01-29T20:04:10.108Z","dependency_job_id":"b901aaa9-fe22-4a52-b4ca-6a3cec62c0d0","html_url":"https://github.com/richardd3ng/Shelf-Stability-System","commit_stats":null,"previous_names":["richardd3ng/shelf-stability-system"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardd3ng%2FShelf-Stability-System","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardd3ng%2FShelf-Stability-System/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardd3ng%2FShelf-Stability-System/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/richardd3ng%2FShelf-Stability-System/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/richardd3ng","download_url":"https://codeload.github.com/richardd3ng/Shelf-Stability-System/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247792923,"owners_count":20996896,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["material-ui","nextjs","postgresql","prisma","react","sendgrid","swagger","vercel"],"created_at":"2024-10-11T13:08:35.322Z","updated_at":"2026-01-20T00:40:59.550Z","avatar_url":"https://github.com/richardd3ng.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Shelf Stability System\n\n## Login Guide\nLogging in via Duke SSO registers your account as a non-admin user with limited priveleges. To login as the super admin, use\n- Username: admin\n- Password: superStabilityTracker378\n  \nNote that logging in as an admin grants you full read/write access to the system, so please do not abuse this by deleting entities you didn't create or overloading our database. Thanks!\n\n## Developer Guide\nThis app uses [Next.js](https://nextjs.org/) to have both frontend and backend code contained within a single codebase with a RESTful API to connect them. We use [Prisma](https://www.prisma.io/) as an ORM to communicate with our database in a type-safe way.\n\nWe use a postgres database with the tables `Assay`, `AssayResult`, `AssayType`, `AssayTypeForExperiment`, `Condition`, `Experiment`, and `User`. Experiments have some number of Conditions, as expressed by an experiment id in each condition, and some number of AssayTypeForExperiments. AssayTypeForExperiment serves as a table mapping assay types for a specific experiment to the associated technicians, along with any future experiment specific data. Assays have ids for an Experiment, Condition, and AssayType that they belong to. There is no limit on how many Assays may link to a given Experiment or AssayTypeForExperiment. We also use two different views: `AssayAgendaView` and `ExperimentWeekView`. The exact details of our database schema are in the `prisma/schema.prisma` file.\n\nFor development:\n- Install Node.js v21.6.1. We recommend using [nvm](https://github.com/nvm-sh/nvm) for this\n- Clone this GitHub repository\n- Create a `.env` file in the root of the project with the format shown below. The details for populating this file will be provided by someone who knows them.\n```\nDATABASE_URL=\"\u003cdatabase connection string\u003e\"\nNEXTAUTH_SECRET=\u003csecret\u003e\nNEXTAUTH_URL=\u003cpublic address of the webserver\u003e\nDUKE_CLIENT_ID=\u003cSSO client ID\u003e\nDUKE_CLIENT_SECRET=\u003cSSO client secret\u003e\nSENDGRID_API_KEY=\u003csecret\u003e\nSENDER_EMAIL=\u003cemail address of sender for email service\u003e\n```\n- In the root of the project, run `npm install`\n- Run `npm run dev` to start the webserver. You should now be able to access it at [http://localhost:3000](http://localhost:3000)\n\n## Deployment Guide\n\nWe started with an Ubuntu 22.04 server with the following packages installed:\n- Node.js v21.6.1 (installed through [nvm](https://github.com/nvm-sh/nvm) although this method is not required)\n- nginx\n- [pm2](https://www.npmjs.com/package/pm2) (Optional, but useful)\n- postgresql (if hosting the database on the same machine, however we will not be detailing how to setup the database software) \n\nClone this repository to somewhere on the machine. Create a file called `.env` in the root with the format\n```\nDATABASE_URL=\"\u003cdatabase connection string\u003e\"\nNEXTAUTH_SECRET=\u003csecret\u003e\n```\nReplace the database connection string with whatever connection string is used for the database you're using and the secret with some random string of your choice (an easy way to generate this is with `openssl rand -base64 32`). These instructions assume your database software is already running somewhere it can be reached from the server.\n\n`cd` into the project root and run the following commands:\n\n```bash\nnpm install # Install all required packages\n\n# If starting a fresh install with no data:\nnpx prisma migrate deploy # Deploy the database schema\n\n# If restoring from a backup\npg_restore -U postgres -d postgres -1 \u003cpath/to/your/backup.sql\u003e\n```\n\nThen start the webserver. \nFor a production environment, run this to build the project:\n```bash\nnpm run build\n```\nFollowed by this to start the server:\n```bash\nnpm run start\n```\nor if you're using pm2\n```bash\npm2 start npm --name \"prod\" -- start # \"prod\" may be replaced with a name of your choosing\n```\n\nTo launch the webserver on boot with pm2:\n```bash\npm2 startup\n\n# Paste the command it instructs you to run\n\npm2 save\n```\n\nThe webserver will now be accepting http requests on port 8080. `nginx` will be needed to get it accepting https requests on port 80.\n\nThere are many ways to configure nginx to achieve this, however, this was our method\n- In `/etc/nginx/nginx.conf`, within the `http` block, add:\n```nginx\nserver {\n    server_name \u003cyour domain name(s) here\u003e;\n    location / {\n        proxy_pass http://localhost:8080;\n    }\n}\n```\n- In the same file, comment out the following lines (although perhaps useful, we did not need these):\n\n```nginx\ninclude /etc/nginx/conf.d/*.conf;\ninclude /etc/nginx/sites-enabled/*;\n```\n- Follow the instructions on the [Certbot website](https://certbot.eff.org/instructions?ws=nginx\u0026os=ubuntufocal) to obtain and install an HTTPS certificate\n\nThe first time you connect to the website, you will be presented with a page to setup the initial admin password. It is recommended to do this sometime before the server can be accessed from outside the network.\n\n## Backup Guide\nOur backup system is implemented using a cron job that SSHs into the webserver and dumps a backup using postgres's `pg_dump` utility. Progress notifications and failure alerts are sent using a discord webhook (although other alerts should be relatively simple to set up).\n\nTo set up this system:\nInstall python and [paramiko](https://www.paramiko.org/)\n\nEdit the constants in `scripts/make-backup` to specify the folder to save backups to, the authentication details to retrieve backups from the production server, and the webhook url to post updates and alerts to.\n\nCopy the script into `/etc/cron.daily`. Make sure the file is owned by the root user and that no other users or groups have write access to it.\n\nThe files output by the backup system are long sets of SQL commands. They can easily be run by the database using the `pg_restore` command:\n```bash\npg_restore -U postgres -d postgres -1 \u003cpath/to/your/backup.sql\u003e\n```\nThe username you use may be different depending on your SQL server setup. Note that this may conflict in minor ways if the database is not empty, so you should wipe the database before restoring a backup.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichardd3ng%2Fshelf-stability-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frichardd3ng%2Fshelf-stability-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frichardd3ng%2Fshelf-stability-system/lists"}