Giter Club home page Giter Club logo

alakajam's People

Contributors

aurel300 avatar coxm avatar dependabot[bot] avatar dollarone avatar magnetomax avatar mkalam-alami avatar niciusb avatar olivier-grech avatar pixelsyntax avatar pta2002 avatar raindrinker avatar schweller avatar shoozza avatar thrainsa avatar ttencate avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alakajam's Issues

Prettier event box

  • Name on a cleared line
  • Details listed below, using glyphicons to gain space, maybe in a neutral well
  • Try listing games using special thin thumbnails (gog-like)
  • List Upcoming/Open/Closed with the games in the Event page

Scalability issues to solve later

Comment system

  • Comment model: id, user_uuid, user_name, parent_id, node_uuid, body, (timestamps).
  • Create a comment system as a macro reusable for any page (pass a node_uuid as a param). It should be set up both on entries and blog posts (maybe also on user pages...?)
  • Make it look loosely like Github issues (and don't support comment parents for now)

  • Comment model
  • Display comments in posts
  • Comment markup
  • Make the Edit button enable the comment form (use query param to pass the comment ID + anchor at comment ID)
  • Make the Save button save changes and redirect back to the current page + anchor at comment ID
  • Make the Cancel button refresh the page (without query param + anchor at comment ID)
  • Make the Delete button delete the comment (& refresh the page)
  • Permission checks (upon Edit & Save & Delete)
  • Store comment counts in posts & display it

Catch all internal errors

Due to the promise-based code, if we want to handle internal errors we have to do that:

async function myRoute (req, res) {
  try {
      .... // do stuff
  } catch (e) {
    res.errorPage(500, e)
  }
}

A bit verbose if we duplicate this on every route...

Some possible solutions are listed here. We could also make a custom wrapper for our routes.

Use Knex migrations

Suppose version 2 adds a table T, and version 3 adds a foreign key to table U that references T, then we can't upgrade U from version 1 to 3 in one go. Rather, we must first upgrade both T and U to version 2, and then both T and U to version 3.

In the same vein, if table V is added in version 2 and a foreign key into V is added to table U also in version 2, then we must ensure that these upgrades happen (and un-happen) in the right order. So simply going by the ordering in models/index.js might not always be sufficient.

Maybe we should just use Knex's migrations system instead? I also just noticed a section on seed files. I'm new to Knex and Bookshelf, so I don't know whether these will do what we want.

"People" page

Add a "People" page besides the "Events" one that simply lists all the users of the website. Use/improve the _macros-user.html > userThumb macro.

Basic user profiles

Users should have an editable profile page (at user/:name), featuring:

  • Arbitrary Markdown contents (see body column. Bonus: refactor the WYSIWYG editor used in the entry-edit.html page to something more reusable, like a _page-editor.html template)
  • A list of the user's entries (displayed by reusing _macros-event.html#entryThumb() I guess)
  • Whatever cool stuff can be easily added (maybe social links?)

All entry thumbnails should display a link to the user profile.

Polish announcements

  • Let mods create event-related announcements using the mod bar
  • Let mods create event-related announcements from the mod dashboard (check for liveEvent/nextEvent)
  • Don't attach event-related announcements to the mod game
  • Don't show unpublished posts on the home page
  • Center comments if the Related block is empty(...?)
  • Always display the latest announcement in the event bar
  • Make the latest announcement link actually lead to the feed of announcements for this event

Don't lose changes if form validation failed

At least while editing an entry.

In general we need to set up a good pattern throughout the site.

EDIT: Possible pattern = update the model before running validation, then use the updated model whatever happens to fill the page.

Store game platform information

Requires #28

  • Make the user choose the title from a dropdown instead of just plain text (Play: Windows/Linux/Mac/Web - Other: Sources, Soundtrack, Custom link), with the "Custom Link" option enabling a text field instead.
  • On the entry thumbnails, use the links info to display platform icons
  • Set up an entry_platform table (with one row per platform), and store platform info there upon entry save. entry_platform will be useful for the future search forms.

Improve file storage API

  • Right now the "isUpload" flag is confusing. An alternative would be to always assume it as false and expose a function to explicitly prepend the uploads folder.

  • Add a resize function using https://github.com/lovell/sharp. Use it for both avatars (256px max) and entries (960px max). No cropping for now.

  • Maybe the move function should be replaced with a saveTmpPicture one, that resizes all pictures automatically and provides options to customize resizing.

Blog posting in events

Requires #4

Any user can make posts in an event. The UI changes involve:

  • Creating a "Feed" tab in the event header (for lack of a better name...)
  • The feed tab features all blog posts with a valid publication time & event id, sorted by publishing time. Plus a little panel inviting the user to create a blog post.
  • Add buttons for the mods.
  • All past posts made by the user can be found behind a "My posts" link in the User dropown.
  • Feature somehow a wait to find easily our own blog posts from the event/entry itself.
  • Rename all "settings" pages to "dashboard"

Normalize indenting

Sublime Text doesn't indent Standard JS correctly: JSDoc tags just offset everything by 1 space or more, and standard --fix doesn't even fix that. I've tried various Sublime Text plugins without success.

I can't find any similar issues on the web though so maybe it's a local problem.

example

Build system / Client-side dependency management

If we run the server in production mode, Nunjucks should disable the style/script blocks and just use a minified version of CSS/JS files.

The build system should also apply the NextCSS filter to the site CSS.

Consider Browserify (run build on startup in development)

In development, either serve directly from node_modules (how could we do that without duping script listing?), or use the browserify build as well.

Set up .browser-refresh-ignore

Right now the browser refresh tool uses the .gitignore file to know when to restart the server/browser, which is not perfect.

Expected differences compared to .gitignore:

Exclude

  • .git
  • File uploads/Data

Include

  • config.js

Config validation on boot

Developers might get issues related to having an out-of-date config.js. During boot, we should compare it with the config.sample.js to show warnings if any key is missing/superfluous.

(special case: only check for DB_SQLITE_FILENAME if DB_TYPE=sqlite3)

Theme voting system

Iteration 1: Theme submission/voting

  • Theme model: id/event_id/user_id/score/notes/flags/status[=active/out/flagged/shortlist]/ts
  • Theme vote model: id/theme_id/event_id/user_id/score/ts
  • Event Details model: theme_count, active_theme_count
  • Make it possible to submit up to 3 themes
  • AJAX API: Fetch a random, not ours, not rated theme
  • AJAX API: Vote on a theme (+1 or -1)
  • Make it possible to vote on a theme

Iteration 2: Progress/Results

  • Display the history of the last 30 votes & let the user change them
  • Handle duplicates
  • Let the user know how many theme she rated
  • Refresh the event details info on each theme submission creation/deletion
  • Every 10 votes, eliminate the lowest ranking one (it must have at least 5 notes)
  • Display a stack progress bar showing the theme_count/active_theme_count/fixed shortlist with the goal to make the active_theme_count = fixed shortlist.
  • Show theme voting stats
  • Let admins set event status_theme = 'results'
  • If event status_theme = 'results', show instead the 10 highest scoring themes, making the winning one stand out.

Iteration 3: Shortlist voting/Security

  • Let admins set event status_theme = 'shortlist'. If set, pick the 10 highest scoring themes & mark them as shortlist. All the other ones must be marked as out.
  • If event status_theme = 'shortlist', show the 10 highest scoring themes, let the user rank them and save the changes (yields a score from 1 to 10 replacing the current user vote). Use https://github.com/RubaXa/Sortable
  • Show the submitted theme status (active/out/shortlist), show its score (out in {{notes}} rounds) if its out
  • Prevent removing a theme that is out or shortlisted
  • Make sure we prevent voting/shortlisting when not appropriate
  • Let admins ban themes

Iteration 4: Polish

(fill this as we find tweaks to make)

Submission/Voting phase

1

Shortlist phase

2

Results phase

3

Create/edit/remove events

Requires #2

The admin bar should feature buttons to let admins edit/delete an event (from the event view page), or create a new one (from the event listing page).

The event creation/edition form should at least let the admin set:

  • Title
  • Display dates
  • Display theme
  • Status (from a dropdown, among "pending/open/closed")

Bonus:

  • Theme/Entries/Results status (among "on/off/disabled" + alternately a blog post ID to display as a temporary way to run theme voting/results listing until the appropriate systems are made)
  • A logo

Launch a first event!

Remaining tasks:

Should be done before launch

  • BUG Post Timstamps
  • TWEAK Home: Try using icons instead of the event table
  • TWEAK Posts try putting related links besides the title
  • TWEAK Make announcements even more obvious
  • &

Can be done after launch

  • Link to the Twitter account etc. more obviously on the home page
  • Mention mods & admins in user profiles
  • Verify the mimetype of uploaded pictures to make sure they are pictures
  • Don't lose changes if form validation failed on the server-side (at least while editing an entry)
  • Daily data backups
  • Write the Help(/rules) page
  • Let admins delete users
  • Log dangerous actions for traceability
  • Show last event on home page if no live event

Choose license

I just realized I never picked a license...

I'm considering a slightly modified MIT license, that just makes sure hypothetical forks don't reuse the Alakajam! name and logo (maybe color scheme as well).

@ttencate @coxm do I have your blessing?

Lets admins edit other users

It should mostly look like the dashboard pages, except they don't need to type the original password to set a new one.

Mods should not have access to that for now (until we get good traceability).

Fix horizontal alignment

Various elements of the pages aren't horizontally aligned: they either stick out into the left/right margin, or are indented on the left/right. This is because of assumptions Bootstrap makes: rows may only contain cols, and containers must not be nested. So the typical hierarchy is:

container > row > col > row > col > ...

Nesting of containers will mess up the padding, because containers add padding that is supposed to be cancelled out by negative margins in the rows.

This is easy to fix by removing superfluous containers, and adding some extra divs where necessary.

Special post type: articles

Set up a help page (available from the main bar) which is simply a blog post (special post type = 'article') with a "hard-coded" reference by name/title.

The DB samples should include a basic help page, e.g. explaining the process for password recovery.

In events, theme/results status should let admins reference an article by ID, to display as a temporary way to run theme voting/results listing until the appropriate systems are made

Blog posts core

  1. Create the model for blog posts (See suggested model here)
  2. Implement a first, simple use of blog posts: the home page should feature a single blog post with the special_post_type column set at announcement. That blog post should be made editable from the admin page (reuse the WYSIWYG editor from entries).

Remaining tasks:

  • Prettier post appearance, with meta info (author, date, etc.)
  • Allow to publish/unpublish/set publication date
  • Put post editing under its own URLs
  • Permission checks
  • Only show post if published
  • Multiple annoucements
  • Allow to delete posts

Transaction management

Provide a simple way to make multiple write queries in the same transaction.
While we're at it, look into pooling.

Security pass

I'm gathering here all the security flaws we can find:

  • Names should be unique
  • Permission checks: people should not be able to create several entries on an event
  • Permission checks: people should only be able to update their own entries/comments
  • Permission checks: people should only be able to use enabled event tabs
  • Set size limits in fields
  • Look for XSS holes (e.g. sanitize all Markdown/HTML inputs. Open tags can break the page)
  • Required fields should also be required on the server-side
  • Make sure that pictures are actually pictures
  • Validate query params
  • Usernames should be case-insensitive (use specific index)

Not really related but we also need to make sure the core DB model looks good (indexes? split table infos e.g. user.body?) before we launch the first event. Social links as JSON?

Also add a tooltip for the invite key thing in the register form.

Support multiple game links

Links are stored as a JSON array in the entry.links string column*.

Right now when editing an entry, things are hard-coded to use a single link (see entry-controller.js and edit-entry.html, with a hard-coded label. With the help of some JS in the template, we could allow people to add more link fields.

*NB. I chose to do this for performance, since we want to limit the number of joins when displaying an entry. This will prevent us from using links to let people search games by platform though. For that see #31. Discussion welcome.


  • Let the user edit the link title with a text field (just like on ludumdare.com)
  • Support adding and removing links

"Admin bar": let admins edit any entry

The footer should feature new templating blocks {% block mod_bar %}{% endblock %} and {% block admin_bar %}{% endblock %}.

They can then be personalized on any page to add custom, yellow buttons only available to mods/admins (see user.is_mod / user.is_admin columns).

A first button would be to let both mods & admins edit any game when on the "view entry" page.

Note: server-side permission checks will be done through #3. This issue is client-side only.

Support teams

EDIT: Polishing pass

  • Merge the manage team page with the manage entry one since it now uses AJAX & stuff
  • Make the field appear dynamically & only if the entry is set to "Team"
  • Clear user roles manually when deleting an entry/post (follow-up to #93)
  • Handle the case where the entry is set back to Solo
  • Make the "category/manage team" fields read-only for non-owners (+ appropriate server checks)
  • Replace the "Delete" button for non-owners (it should not work anyway) with a "Leave team" button
  • Fix SQLite support (ILIKE)
  • Fix not being able to clear the team
  • Make the field fill the whole width
  • Display a warning if a user is about to clear his team (check + confirm dialog with JS upon Save)
  • Make it more clear that the first role cannot be deleted because he's the owner (maybe even put him outside the field?)
  • Make it more clear (CSS+maybe message?) that some users cannot be added
  • Sort user roles for display
  • Server-side check for changing the game category

Entry edit page

  • Add solo/team toggle in entry edit form, with a tooltip saying that the team can be managed after saving (model field: entry.category)

Entry view page

  • List user roles on the entry sidebar (use and improve the _macros-user.html > userThumb macro styling
  • If the entry is team-based show in the entry sidebar a "Manage team" link leading to a separate page

Team management page

  • List the entry user roles
  • AJAX API that renders only one user, by its name (in HTML)
  • Add username field + button to let users add new user roles in Ajax (not saved yet).
  • Add "Save changes" button to apply team changes. All non-owner user roles are cleared then rebuilt from the form contents. Users are added with a "write" permission. Owner cannot be changed.
  • Add "Restore" button which just refreshes the page
  • Add a little button on each user role (except the owner) to remove them in JS
  • Prevent users from joining multiple teams (if only because of UI limitations)
  • Let people leave a game they have been added to

Tests

  • Check that non-owner users can edit the entry
  • Check that non-owner users are listed on entry thumbs
  • Check that non-owner users can make posts related to the entry
  • Check that non-owner users have the entry on their profile

Key-powered invite system

A simple invite system would make us less concerned by security issues, because we'd have trusted members only. The process:

  • Existing users can generate Steam-like keys from a page accessible in the user dropdown menu (they're not persisted, there's just a big "generate" button)
  • They share the key
  • People must fill a big "Invite key" field to register

How it would work:

  • The server stores a random key + a random pepper in database
  • Invites are generated by concatenating the pepper with a random string, then encrypting with the key.
  • We don't store the invites server-side, just decrypt with the key and look for the pepper in the result.

Not super safe, but simple enough.

Note: plenty of code can be reused from the Sessions service

Nicer URLs

Replace all uuid-based URLs with name-based ones. It involves:

  • Making sure all entries/events have a name, generated automatically from the title in entryController.js#saveEntry (without worrying about name-clashing for now).
  • Updating the entry & event controllers routes
  • Updating the controllers/templating.js#buildUrl() function

Tip: updating the samples in core/db.js#insertSamples() to test stuff will be useful.

Add a token to the session cookie

Upon creating a session cookie, generate a token on the server and store it so that we can match it when the cookie is used.

Not doing that might lead to people getting logged as someone else in very specific corner cases (e.g. following a rollback).

For retro-compatibility, if no ID is present in the session cookie, accept the cookie(?).

"EventEmitter memory leak" messages / Replace node-formidable library

Node sometimes logs warnings like:

(node:8088) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 field listeners added. Use emitter.setMaxListeners() to increase limit
(node:8088) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 file listeners added. Use emitter.setMaxListeners() to increase limit
(node:8088) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 error listeners added. Use emitter.setMaxListeners() to increase limit
(node:8088) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 end listeners added. Use emitter.setMaxListeners() to increase limit

It must be worth investigating.

Declare the mod bar in a single place

Right now the yellow mod bar is declared in each page with custom buttons according to the context. It turns out to be a bit heavy and repetitive.

A better approach instead would be to declare the mod bar in a single place (why not directly in _page.html for now), declare all buttons there and just toggle them according to which context variables are present (e.g. show "Edit entry" button if the entry variable is there).

Code review

Skim through the code and check the following things:

  • TODOs left in the code should be done or turned into issues
  • The service & model layers should be documented
  • Naming & code structuring should be consistent
  • Easy performance optimizations (*)

Other tasks:

  • Check where the code deals with size limits in fields
  • Validate devenv setup from a fresh install
  • Test production mode
  • See how bad the performance & UX gets with >1000 entries (fill the DB with Feedback Friends/Ludum Dare data), and list what needs to be done to make things acceptable

(*) Right now the amount of SQL queries per request is not pretty:

Front page

  sql: 'select "user".* from "user" where "id" = ? limit ?' }
  sql: 'select "event".* from "event" where "status" = ? order by "event"."created_at" ASC limit ?' }
  sql: 'select "entry".* from "entry" where "entry"."event_id" in (?)' }
  sql: 'select "user_role".* from "user_role" where "user_role"."node_id" in (?) and "user_role"."node_type" = ?' }
  sql: 'select "event".* from "event" where "status" = ? order by "event"."created_at" DESC' }
  sql: 'select "entry".* from "entry" where "entry"."event_id" in (?)' }
  sql: 'select "post".* from "post" where "special_post_type" = ? order by "post"."published_at" DESC limit ?' }
  sql: 'select "user".* from "user" where "user"."id" in (?)' }
  sql: 'select "user_role".* from "user_role" where "user_role"."node_id" in (?) and "user_role"."node_type" = ?' }

Event posts

  sql: 'select "user".* from "user" where "id" = ? limit ?' }
  sql: 'select "event".* from "event" where "status" = ? order by "event"."created_at" ASC limit ?' }
  sql: 'select "event".* from "event" where "name" = ? limit ?' }
  sql: 'select "entry".* from "entry" where "entry"."event_id" in (?)' }
  sql: 'select "user_role".* from "user_role" where "user_role"."node_id" in (?) and "user_role"."node_type" = ?' }
  sql: 'select "post".* from "post" where "special_post_type" = ? and "event_id" = ? order by "post"."published_at" DESC limit ?' }
  sql: 'select "entry".* from "entry" inner join "user_role" on "entry"."id" = "user_role"."node_id" where "entry"."event_id" = ? and "user_role"."user_id" = ? and "user_role"."node_type" = ? limit ?' }
  sql: 'select distinct "post".* from "post" inner join "user_role" on "post"."id" = "user_role"."node_id" where "special_post_type" is null and "event_id" = ? and "user_role"."user_id" = ? and "permission" in (?, ?) and "published_at" <= ? order by "post"."published_at" DESC' }
  sql: 'select distinct "post".* from "post" where "special_post_type" is null and "event_id" = ? and "published_at" <= ? order by "post"."published_at" DESC' }
  sql: 'select "user".* from "user" where "user"."id" in (?)' }
  sql: 'select "user_role".* from "user_role" where "user_role"."node_id" in (?) and "user_role"."node_type" = ?' }

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.