GithubHelp home page GithubHelp logo

andrei0872 / decentdebates Goto Github PK

View Code? Open in Web Editor NEW
9.0 9.0 3.0 1.64 MB

A place where all sorts of topics are debated in a respectful and constructive manner.

TypeScript 89.64% JavaScript 0.23% SCSS 10.13%

decentdebates's People

Contributors

andrei0872 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

decentdebates's Issues

User: inspect an item

❗ As opposed to a moderator, a user can review their ticket regardless of whether it has a moderator assigned to it.


  • endpoint for fetching debate information as a user
  • endpoint for fetching argument information as a user
  • debate: under the title, show something like Reviewed by moderator.username
  • argument: show something like Reviewed by moderator.username
  • edit argument
  • edit debate
  • view debate from activity
  • view argument from activity
  • fix: if request to review endpoint returns no data -> error + redirect to login page. it means that the ticket either has no moderator assigned or the moderator that performs the request is different than the one assigned to the ticket
  • disconnect when errors occur; idea: socket.disconnect() in removeUserFromRoom()

How to set-up the database

  • filling in the .env file
  • running docker-compose
  • recommending the VS Code extensions - either Postgres Explorer or SQL Tools
  • show a few examples
  • describe the db folder
  • mention knex's commands for seeding

Why I decided not to use an ORM

Personal conclusions:

  • I really like writing SQL and make use of the database-specific features
  • I don't think it's possible to reach a very good level of abstraction when the project's complexity increases
  • you have to keep the ORM definitions in sync with the underlying database schema(3))
  • fewer moving parts that you need to worry about(4))
  • an abstraction is less likely to be as flexible and as performant as the native querying language(4))
  • (5)) > ORMs often generate complicated queries for relatively simple database operations, because they employ general patterns that must be flexible enough to handle other cases
  • transactions are very important(6))

References:

  1. https://dev.to/harshhhdev/why-orms-arent-always-a-great-idea-41kg
  2. https://youtu.be/nIyToKVh44s
  3. https://www.edgedb.com/blog/a-solution-to-the-sql-vs-orm-dilemma
  4. https://www.prisma.io/dataguide/types/relational/comparing-sql-query-builders-and-orms
  5. https://www.prisma.io/dataguide/types/relational/comparing-sql-query-builders-and-orms#drawbacks-of-orms
  6. https://levelup.gitconnected.com/raw-sql-vs-query-builder-vs-orm-eee72dbdd275
  7. https://calpaterson.com/activerecord.html

Add debate page

The user should see the following:

  • the for arguments on the left side
  • the against arguments on the right side
  • right before the arguments, there should be some action buttons:
    • Add argument

Notes about the arguments:

  • all arguments should have the same size(truncated, if needed)
  • an argument should be able to be expanded(while remaining in the same page) so that its content is inspected

User's actions:

  • add an argument;
    the user should be notified afterwards;
    required fields for:
    • content
    • for or against
  • add a counterargument to another argument;
    this implies than an argument will have a button(or something) that will allow to creating a counterargument for it
  • for a given argument, there should be a way to see all of its direct counterarguments
  • for a given argument, there should be a way to see a thread of arguments, starting from the aforementioned one

Moderator: a Kanban board

In this board, a moderator should have the following lists:

  • Pending
  • In Review
  • Approved

Types of cards(tickets):

  • new argument
  • new debate
  • suggestion
  • complaint

Notes about this page:

  • just like in Jira, all moderators will share the lists
  • there can be only one moderator assigned to a card
  • the board should be realtime
  • after a card has been approved, it will materialise(in either an argument or a debate)

Technical considerations:

  • for example, when a new debate is created, have a stored procedure that will do: 1) creating a corresponding ticket in the ticket table and adds a new row in the debate table

Add DB table for reports

This could be a good start for the report table:

report:
  - id
  - ticket_id
  - title
  - content
  - reporter_id
  - reported_it

User: add argument/counterargument

Argument:

  • content
  • for or against

After creating an argument, show a toaster which will let the user know that.


  • WYSIWYG editor
  • collect argument data on submit
  • specify whether the argument is a counterargument for another argument(could be done at the top of the page and the user will be able to choose which argument the current argument is a counterargument for)
  • endpoint for creating an argument
  • an argument should have an option Add counterargument; when that is chosen, the user should be redirected to the create argument page, where the counterargument should be already shown
  • (server): check if the argument's insertion was successful on a debate that does not exist(might need to check the affected rows count)
  • modify argument card such that the title is actually part of the body and, upon expansion, load the entire serialized editor state
  • delete the external_reference table
  • protect client route: only auth user
  • new-argument: check serialization & deserialization
  • redirect to debates if /new-argument does not have crtDebate populated
  • include debate's title when creating arg
  • handle the case where there are no args in a debate
  • display content when accordion expanded
  • endpoint for fetching an argument
  • create argument from UI
  • show a toaster that will let the user know how the action went
  • form types

Notifications

Research

  • ✔ notification content - should use rich editor? - Yes
  • ✔ SSE
creating notification content on the server
  const onFoo = () => {
    const editorOrig = exportEditorContentRef.current?.getEditor();
    if (!editorOrig) {
      return;
    }

    // console.log(JSON.stringify(editorOrig.getEditorState()));

    // return;

    const editor = createEditor({ nodes: [LinkNode], namespace: 'decentdebates' });
    editor.update(() => {
      const root = $getRoot();

      const t1 = $createTextNode('ANDREI');
      const b1 = $createTextNode('BOLD');
      b1.setFormat('bold');

      const link = new LinkNode('https://andreigatej.dev');
      link.append($createTextNode('my website'));

      const p = $createParagraphNode();
      p.append(t1, b1, link);

      root.append(p);

      editorOrig.update(() => {
        const link = new LinkNode('https://andreigatej.dev');
        const p = $createParagraphNode();
        const b1 = $createTextNode('BOLD');
        b1.setFormat('bold');

        link.append(b1);
        
        p.append(link);

        $insertNodes([p]);
      });

      setTimeout(() => {
        console.log(JSON.stringify(editor.getEditorState()));
      }, 0);
    });
  }

There are 2 types of notifications:

  • one which redirects to another page
  • simply informative

Questions/Bugs

  • what happens if a user/moderator receives a notification while they're reading the notifications?
  • close the connection on log out
  • when redirecting from a notif - ensure the page is not refreshed

Debate Page

  • accessed by: auth user. user

On the left, pro arguments(greed bg), on the right, con arguments(red bg).

Notes about the arguments:

  • all arguments should have the same size(truncated, if needed)
  • an argument should be able to be expanded(while remaining in the same page) so that its content is inspected

My Activity: moderator

  • types of items(i.e. cards) to be reviewed: new argument, new topic(debate), new user report
  • all moderators will share the lists
  • lists: pending, in review, blocked(i.e. requesting for changes), done, approved
    • pending
    • in review
    • canceled
    • done

Notes about this page:

  • just like in Jira, all moderators will share the lists
  • there can be only one moderator assigned to a card
  • the board should be realtime
  • after a card has been approved, it will materialise(in either an argument or a debate)

Card information:

  • both items: debate's title
  • new debate: green label + scroll icon
  • new argument: light orange label + comment icon
  • both items: the user in question + user icon
  • both items: the assignee

At this point, it is enough to only include debates as part of the moderator's activity.


  • layout: Kanban board
  • drag & drop
  • after dropping an item: make request so that item is saved in the new board
  • after taking the item from Pending and moving it to the In Review list -> assign the moderator to that ticket
  • moving the ticket back to Pending -> unassign
  • clicking on that item -> open modal
    information to be displayed(for debate): title, created_at, created_by, label, comments + expand icon in the top right corner
  • allow 'expanding' that item -> open in new page
  • endpoint for fetching all the board's tickets
  • highlight the moderator's tickets
  • add role guard on API
  • add role guard on client
  • prevent from moving cards that don't belong to a certain moderator
  • return the data from the API by grouping them by boardList
  • fix missing props from card information
  • (api): prevent a moderator from making changes on behalf of other moderator
  • endpoint for updating a ticket

My Activity: user

Types of ongoing items:

  • new debate
  • new argument
  • argument draft(icon)

Card information:

  • header: the type of item + color + corresponding icon
    debate - green; argument - blue; draft - light orange;
  • body: debate title
  • the ticket's status(pending, in review, etc.)

  • page layout(Figma)
  • see the status of an item(new argument/new topic) handled by a moderator
  • seed with items of a different status
  • endpoint that fetches ongoing items
  • endpoint that fetches solved items

Admin: ban users

Could be implemented after #5 is done.

An admin should be able to see the reports and, if needed, ban certain users.


Technical details:

  • a new banned_user table might be needed

Debates feed: search based on title

  • collect input
  • debounce on input
  • fetch tags for each debate
  • endpoint for searching based on a string
  • endpoint validation pipe
  • make it work in the UI

Debates feed

On this page, the latest debates will be shown.

In order to customise their feed, the user should be able to:

  • search for debates based on keyword(e.g. a text input)
  • search for debates based on tags(e.g. a 'tag' component) - the tag feature has been left for later.

Irrespective of whether the user is authenticated or not, they can perform the above actions.
The only difference is that only the authenticated user can interact with the app(i.e. proposing a debate).


  • accessed by: auth user, anon user

Optimize DB schema

Notifications: add widget

  • bell icon that has a number which indicates the number of unread notifications
  • view the notifications in a tooltip
  • endpoint for fetching notifications for an auth user
  • fetch notifications count
  • add loading spinner while fetching notifications
  • show merely read notifications

Commenting System

An auth user & moderator should be able to communicate via comments.

They could communicate on:

  • a new argument proposed by a user
  • a new debate proposed by a user

The comments should be added when an item is inspected.

item: new argument, new debate.


Features:

  • reply to a comment; the comment that is being replied to should be part of the replying comment

  • when item == new argument: preview the addition of the new argument(will allow to see arguments and decide if the current one fits well.
  • when an item becomes approved: from item -> argument/debate - created ticket
  • show that there are unread comments for a certain ticket - created ticket
  • make comment part of the moderator's activity(i.e. somehow show them that they have received a comment) - created ticket
  • debate modal + expand
  • argument modal + expand

Complete DB schema

  • db schema
  • UML; update: decided it's better to create & expose the UML after the project has gained some maturity
  • docker-compose file

User: add Activity page

Here, the user should be able to see all the items. The layout could be made up of 2 card sliders:

  1. pending items
  2. resolved items

Note: items = arguments/debates.

Debates feed: tags

Besides showing the selected tags, the user should be able to specify whether there should be an && or an || action between them.


  • include an include_tags query on GET /debates that will also return all the available tags - can be done on the client: determining the set tags from all the fetched debates
  • add Tags component
  • add tags filter in UI
  • search based on debate tag; take && and || into account
  • display tags in debate card
  • tags when proposing a debate
  • ensure debates can be proposed
  • add tags when reviewing a debate as a user
  • avoid inserting duplicate tags; use a where clause
  • when fetching tags, ensure only those whose debates are ACCEPTED are fetched
  • moderator: display debate tags in activity
  • user: display debate tags in activity

Use stored procedure for user register

There should be a single stored procedure that:

  • checks whether the current user already exists(e.g. based on username or email)
  • if the user exists, throw an error
  • if the user does not exist, create the user

Moderator: preview the addition of a new argument

When reviewing an argument draft, a moderator should be able to get a feeling for how the argument will fit in the debate. In order to achieve that, the moderator can click on an argument's card and be redirected to page where the addition of that argument is simulated.

Add settings page

From this page, a user/moderator can alter their details regarding:

  • the username
  • the photo
  • description

Moderator: inspect an item

  • a CommentsLayout component that accepts mainContent(e.g. debate title, argument content) and renders the comments beneath the main content
  • the comment that is being replied to should be part of the replying comment
  • the rich editor should be used for a comment's content

  • add basic review debate page layout
  • add basic review argument page layout
  • add editable Comment component at the end of the comments list so that a comment can be created
  • add reply_to to comments table
  • add comment to a debate
  • after adding a comment, update the list
  • reply to a comment
  • debate: fetch the debate's metadata(e.g author, created_at)
  • argument: fetch the debate info & author
  • edit a comment
  • protect client route
  • arg review: when clicking on counterargument title -> open sidebar with counterargument content
  • comment: pretty format the date(e.g. 30 min ago) - added to the Improvements ticket
  • add & configure websockets
  • create room for moderator & user discussion
  • add authentication on websockets messages
  • store config data in separate files
  • debate: fetch information on the fly so that user authorization can be done at the same time
  • arg: fetch information on the fly so that user authorization can be done at the same time
  • when adding a comment, ensure the one that adds the comment(e.g. user or moderator) are indeed connected to that ticketId
  • endpoint for fetching comments
  • display fetched comments
  • order comments by created_at
  • fetch the metadata when previewing the debate card
  • ensure a foreign user can't see the discussion between another user & moderator
  • update comment via websockets
  • prevent reviewing a ticket that hasn't been assigned to a moderator yet
  • refactor: move debate metadata request from debate to review entity
  • argument: make comments work
  • argument: protect client route

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.