{"id":13393320,"url":"https://github.com/derrickreimer/level","last_synced_at":"2025-05-16T13:04:47.637Z","repository":{"id":44164158,"uuid":"127781753","full_name":"derrickreimer/level","owner":"derrickreimer","description":"Team communication optimized for deep work","archived":false,"fork":false,"pushed_at":"2023-07-11T17:59:03.000Z","size":8284,"stargazers_count":1013,"open_issues_count":2,"forks_count":92,"subscribers_count":43,"default_branch":"master","last_synced_at":"2024-10-30T00:32:23.133Z","etag":null,"topics":["elixir","elm","graphql"],"latest_commit_sha":null,"homepage":"","language":"Elm","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/derrickreimer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-README.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-04-02T16:23:02.000Z","updated_at":"2024-09-13T07:29:33.000Z","dependencies_parsed_at":"2024-01-24T12:11:17.933Z","dependency_job_id":null,"html_url":"https://github.com/derrickreimer/level","commit_stats":null,"previous_names":["unstacked/level"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derrickreimer%2Flevel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derrickreimer%2Flevel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derrickreimer%2Flevel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/derrickreimer%2Flevel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/derrickreimer","download_url":"https://codeload.github.com/derrickreimer/level/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247999859,"owners_count":21031046,"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":["elixir","elm","graphql"],"created_at":"2024-07-30T17:00:50.174Z","updated_at":"2025-04-09T08:05:38.757Z","avatar_url":"https://github.com/derrickreimer.png","language":"Elm","funding_links":[],"categories":["Elm","graphql"],"sub_categories":[],"readme":"# Level\n\n[![CircleCI](https://circleci.com/gh/unstacked/level.svg?style=svg)](https://circleci.com/gh/unstacked/level)\n\n## Project Status\n\nLevel began with the ambitious idea of [solving the problems](https://www.derrickreimer.com/essays/2018/03/02/the-war-on-developer-productivity.html) caused by real-time communication tools. After pouring thousands of hours effort into the cause, I made the tough decision to move on from the project. \n\n[Read the full story here \u0026rarr;](https://www.derrickreimer.com/essays/2019/05/17/im-walking-away-from-the-product-i-spent-a-year-building.html)\n\nThis codebase is a full-scale Elixir/Phoenix SaaS application with a single-page app Elm front-end. I hope it will live on as a helpful resource for the community.\n\n\u0026mdash; Derrick Reimer, Founder\n\n## Developer Setup\n\nYou'll need to install the following dependencies first:\n\n- [Elixir](https://elixir-lang.org/install.html) ([version](https://github.com/levelhq/level/blob/master/mix.exs#L4))\n- [PostgreSQL](https://postgresapp.com/) 10\n- [Yarn](https://yarnpkg.com/en/docs/install) ([latest](https://yarnpkg.com/en/docs/install#mac-stable))\n- [Node](#nodejs) ([version](https://github.com/levelhq/level/blob/master/.nvmrc))\n\nRun the bootstrap script to install the remaining dependencies and create your\ndevelopment database:\n\n```\ncd level\nscript/bootstrap\n```\n\nIf your local PostgreSQL install does not have a default `postgres` user, open the `config/dev.secret.exs` file and update the credentials. Then, run the bootstrap script again.\n\nUse the `script/server` command to start up your local server and visit [`localhost:4000`](http://localhost:4000) from your browser.\n\n### Installing Node.js\n\nThis repository includes a `.nvmrc` file targeting a specific version of Node\nthat is known to be compatible with all current node dependencies. Things might work\nwith a newer version of Node, but the most guaranteed route is to install\n[Node Version Manager](https://github.com/creationix/nvm) and run `nvm install` from\nthe project root.\n\nThen, be sure to run `script/bootstrap` to install node dependencies with the\ncorrect version of node.\n\n### Running tests and analyses\n\nWe have a handful of helper scripts available:\n\n- `script/elixir-test`: runs the Elixir test suite with coveralls\n- `script/elm-test`: runs the Elm test suite\n- `script/test`: runs the Elixir and Elm test suites\n- `script/static-analysis`: runs Credo (Elixir linting), Dialyzer, and Elixir formatter verification\n- `script/build`: runs all the test suites and static analysis\n\n## Dependencies\n\nThe following environment variables must be set in production:\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eVariable\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003cthead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eAWS\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eAWS_ACCESS_KEY_ID\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe AWS access key id for your account (with access to S3).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eAWS_SECRET_ACCESS_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe AWS secret access key corresponding to the access key id.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_ASSET_STORE_BUCKET\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe name of the S3 bucket in which to store uploaded assets.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eHost\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003ePORT\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe port on which to host the application (typically 80).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_HOST\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe domain on which you are serving the app (used for generating URLs).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_CDN_HOST\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe host for the CDN for serving static assets (like Level's CSS and application JS).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_MAILER_HOST\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe domain via which to send transaction emails (usually same as \u003ccode\u003eLEVEL_HOST\u003c/code\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_SECRET_KEY_BASE\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eA secret key for verifying the integrity of signed cookies.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eDatabase\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_DATABASE_URL\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe URL for the PostgreSQL database.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_POOL_SIZE\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe maximum number of database connections each process may consume.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eTransactional Email\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003ePOSTMARK_API_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe API key for \u003ca href=\"https://postmarkapp.com/\"\u003ePostmark\u003c/a\u003e.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eWeb Push Notifications\u003c/strong\u003e\u003cbr\u003eSee instructions here: https://github.com/web-push-libs/web-push#command-line\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_WEB_PUSH_PUBLIC_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eA VAPID public key.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eLEVEL_WEB_PUSH_PRIVATE_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eA VAPID private key.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\nThe following variables are for non-essential external services.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth\u003eVariable\u003c/th\u003e\n      \u003cth\u003eDescription\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003cthead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eException Monitoring\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eHONEYBADGER_API_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe API key for Honeybadger.io exception monitoring (Elixir).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eHONEYBADGER_JS_API_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe API key for Honeybadger.io exception monitoring (JavaScript).\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eAnalytics\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eFATHOM_SITE_ID\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe site ID for Fathom Analytics.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eFULLSTORY_ORG\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe organization ID for FullStory.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eHEAP_ANALYTICS_APP_ID\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe app ID for Heap Analytics.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eEmail Marketing\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eDRIP_ACCOUNT_ID\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe account ID for Drip.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eDRIP_API_KEY\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe personal api key for Drip.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd colspan=\"2\"\u003e\u003cstrong\u003eSupport\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ccode\u003eHELPSCOUT_BEACON_ID\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003eThe Beacon ID for Help Scout.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n## Documentation\n\nRun the `script/docs` to generate and view the project ExDocs locally.\n\n## Heroku Deployment (Experimental)\n\nOne of our goals is to make self-installation as painless as possible for those who are interested in hosting their own instance.\n\nThe relevant configuration files for Heroku live here:\n\n- [app.json](https://github.com/levelhq/level/blob/master/app.json)\n- [elixir_buildpack.config](https://github.com/levelhq/level/blob/master/elixir_buildpack.config)\n- [phoenix_static_buildpack.config](https://github.com/levelhq/level/blob/master/phoenix_static_buildpack.config)\n- [Procfile](https://github.com/levelhq/level/blob/master/Procfile)\n\nWe are aiming to keep seamless Heroku deployment up-to-date, with a few important \"alpha software\" notes:\n\n- It's possible you may find it broken on master. If you do, please file an issue.\n- As deployment needs grow more complex, it may become no longer feasible to support Heroku deploys. Caveat emptor.\n\n### Required additional services\n\nIn addition to a Heroku account, you'll need the following services to get your Heroku install up and running:\n\n- An AWS account and an S3 bucket for storing file uploads. You'll be asked for AWS API keys and bucket name environment variables during setup.\n- A transactional email provider (we recommend [Postmark](https://postmarkapp.com)). You'll be asked for SMTP host, port, username, and password environment variables during setup.\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy?template=https://github.com/levelhq/level/tree/master)\n\n## Copyright\n\n\u0026copy; 2019 Level Technologies, LLC\n\nLevel is [source-available](https://en.wikipedia.org/wiki/Source-available_software) software. ([license](https://github.com/levelhq/level/blob/master/LICENSE.txt) | [readme](https://github.com/levelhq/level/blob/master/LICENSE-README.md))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderrickreimer%2Flevel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fderrickreimer%2Flevel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fderrickreimer%2Flevel/lists"}