{"id":27295054,"url":"https://github.com/the-launch-tech/bryllyant-polldash","last_synced_at":"2026-07-13T16:32:25.384Z","repository":{"id":40818286,"uuid":"275921538","full_name":"the-launch-tech/bryllyant-polldash","owner":"the-launch-tech","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-12T01:45:29.000Z","size":3990,"stargazers_count":0,"open_issues_count":25,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-08T09:02:09.505Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/the-launch-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-06-29T20:41:23.000Z","updated_at":"2020-06-29T21:14:55.000Z","dependencies_parsed_at":"2023-02-09T09:16:42.575Z","dependency_job_id":null,"html_url":"https://github.com/the-launch-tech/bryllyant-polldash","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/the-launch-tech/bryllyant-polldash","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-launch-tech%2Fbryllyant-polldash","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-launch-tech%2Fbryllyant-polldash/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-launch-tech%2Fbryllyant-polldash/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-launch-tech%2Fbryllyant-polldash/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/the-launch-tech","download_url":"https://codeload.github.com/the-launch-tech/bryllyant-polldash/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/the-launch-tech%2Fbryllyant-polldash/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35429403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-13T02:00:06.543Z","response_time":119,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2025-04-11T22:58:12.701Z","updated_at":"2026-07-13T16:32:25.365Z","avatar_url":"https://github.com/the-launch-tech.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PollDash\n\n### Thoughts\n\nThis was very fun. I've never used TypeORM or NestJS and got rather obsessed. I wish I had scoped things a little better, and that I had more time to learn this particular query building syntax so I could be more concise. There are similarities with the Laravel Eloquent ORM, but TypeORM isn't quite as developed yet - but as far as JS ORM's it's great.\n\nI initially approached things very methodically with the aim of building something that had an architecture that could be expanded with more features rather than just meeting the short-term requirements - just in principle. If I had more time I would continue refactoring the things that were completed towards the end. I also would have used Bootstrap or Material Design instead of doing all the SCSS in order to reduce some overhead in style writing.\n\nWe talked about Generic Types, and this gave me a good oppurtinity to utilize them more. This is a new implementation I've tried for redux-thunks in order to make maximally reusable and typed thunks. It worked really well.\n\n```typescript\nFile: /client/redux/thunks/Generic.ts\n\nexport async function findOne\u003cR, C\u003e(dispatch: WrappedThunkDispatch\u003cnever\u003e, ...options: any[]) {\n  const findOneThunk: WrappedThunkActionCreator\u003cData\u003cany\u003e\u003e = (\n    prefix: string,\n    id: number,\n    callback?: C\n  ) =\u003e async (\n    dispatch: WrappedThunkDispatch\u003cAxiosStatic\u003e,\n    getState: () =\u003e State,\n    Http: AxiosStatic\n  ): Promise\u003cData\u003cR\u003e\u003e =\u003e {\n    try {\n      const response: Data\u003cR\u003e = await HttpService.findOne\u003cR\u003e(Http, { prefix, id })\n      if (typeof callback === 'function') {\n        await callback(response)\n      }\n      return response\n    } catch (err) {\n      throw err\n    }\n  }\n\n  return await dispatch(findOneThunk(...options))\n}\n\nUsage of a \"Generic Thunk\" (create(), but same idea): /client/redux/maps/dispatch.ts\n\n...\ncreateDistribution: async (options: Create\u003cCreateDistribution\u003e) =\u003e {\n  return await GenericThunk.create\u003cDistribution, CreateDistribution, Function\u003e(\n    dispatch,\n    'distributions',\n    options.body,\n    (response: Model\u003cDistribution\u003e): void =\u003e {\n      dispatch(DistributionAction.create(response))\n    }\n  )\n},\n...\n```\n\n---\n\n### Setup\n\n1. Add the .env files to /client and /server roots.\n2. Using `NodeJS 14.4.0`\n\n---\n\n### Start Commands\n\n##### Server (NestJS, Typescript, Postgres, TypeORM)\n\n1. `npm i`\n2. `npm run typeorm:migration:run` - Runs migration\n   - `npm run typeorm:migration:revert` - Reverts migration\n3. `npm run prod:build` - Builds /dist\n4. `npm run prod:start` - Starts from /dist/main.js\n\n##### Client (Server Side Rendered ReactJs, NodeJS, Express)\n\n1. `npm i`\n2. `npm run prod:build` - Builds production bundles\n3. `npm run prod:start` - Starts Express server for SSR, ready\n\n##### Getting Started\n\n1. Admin: admin@example.com, ******** (as in .PDF)\n2. Feel free to register other self-registering Users, or create more as an Admin (you can create Admins, too).\n3. Created User/Admins have a password matching their email.\n4. Create some Groups, and add Users to them.\n5. Create some Polls, and execute Distributions.\n6. Find Mocks after executing Distribution in \"Distribution Meta\" page. Or, use the provided SendGrid API if you are registering real email accounts.\n7. Review \"Response History\", \"Distribution Meta\", and \"Single User\" pages after some activity.\n\n---\n\n### Features\n\n- Multiple admins with individually scoped Users, Groups, Polls, Questions, and Distributions (of polls)\n- Admins can create other Users, or Admins *Admin created users have a password of their email*\n- Users can be placed into admin Groups and Groups can be Distributed Polls\n- Repeater field can be used to build Polls with Questions\n- Each Distribution can be tracked, and each question is a \"yes\" | \"no\" enum response. The statistics are monitored.\n- JWT authentication implemented for role-based access control using NestJS decorators\n- Normal users can login, but only have partial access to views\n- You may be logged out to take the survey you are sent, or logged in\n- The survey email can be mocked but it can also be sent with SendGrid API\n- On boot we seed the table with our admin@example.com\n- The survey link uses a decoded JWT token for tracking\n- More stuff...\n\n---\n\n### Pages\n\n##### Home `/`\n\n   - Public\n   - Landing page\n\n##### Login `/users/login`\n\n   - Public\n   - login page\n\n##### Register `/users/register`\n\n   - Public\n   - registration page (for self-registering users open to all-admin scopes)\n\n##### Dashboard Main `/auth/{id}`\n\n   - User Controlled\n   - general information (a little out of date, you can see that a few of my expectations didn't have time to be completed)\n\n##### User Management `/auth/{id}/users`\n\n   - Admin Controlled\n   - create and view your scoped users\n\n##### Group Management `/auth/{id}/groups`\n\n   - Admin Controlled\n   - Create groups and add users. Users that self register are availaable to your scope.\n\n##### Poll Delegation `/auth/{id}/polls`\n\n   - Admin Controlled\n   - Create Polls and send distributions. You can use SendGrid, or Mock the email.\n\n##### Distribution Meta `/auth/{id}/distributions`\n\n   - Admin Controlled\n   - Mocks links go here. We dig into each admin-created distribution of a poll. A Poll can be distributed multiple times, and each distribution has responses. Here we can view a lot of details about the distribution(s) state.\n\n##### Response History `/auth/{id}/responses`\n\n   - AUser Controlled\n   - View Auth Responses, Received Responses, and Sent Distributions. General Overview.\n\n##### Single User `/auth/{id}/users/{userId}`\n\n   - Admin Controlled\n   - Accessible only through link in Response History. View individual user statistics.\n\n### Issues Encountered\n\n1. On initial compile of NestJS: `No valid exports main found for '/Users/danielgriffiths/Desktop/bryllynt-dash/polldash/node_modules/uuid'`\n   - Solution: Update NodeJS to 14.4.0\n2. Experimenting with TypeORM, wish I could be more acquainted with the Entity and Repository API's.\n\n---\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthe-launch-tech%2Fbryllyant-polldash","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthe-launch-tech%2Fbryllyant-polldash","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthe-launch-tech%2Fbryllyant-polldash/lists"}