alakajam-team / alakajam Goto Github PK
View Code? Open in Web Editor NEWWebsite powering the Alakajam! game making community
Home Page: https://alakajam.com/
License: Other
Website powering the Alakajam! game making community
Home Page: https://alakajam.com/
License: Other
Scalability issues to solve later
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.
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.
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.
Users should have an editable profile page (at user/:name
), featuring:
body
column. Bonus: refactor the WYSIWYG editor used in the entry-edit.html
page to something more reusable, like a _page-editor.html
template)_macros-event.html#entryThumb()
I guess)All entry thumbnails should display a link to the user profile.
Let people add/remove pictures manually from the post. Ideally clicking on the image adds the markup to the editor. Possible mockup:
A possible option could be integrating http://git.razko.nl/InlineAttachment/
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.
Requires #28
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.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.
Prerequisite for #6.
Requires #4
Any user can make posts in an event. The UI changes involve:
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.
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.
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:
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
)
(fill this as we find tweaks to make)
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:
Bonus:
Remaining tasks:
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).
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.
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
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:
Provide a simple way to make multiple write queries in the same transaction.
While we're at it, look into pooling.
I'm gathering here all the security flaws we can find:
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.
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.
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.
Currently any @xxx text will be converted to a link to the user page. Even if it's actually a Twitter link.
Also do we actually need to support mentions inside posts?
Check for event.status
to be open
EDIT: Polishing pass
entry.category
)_macros-user.html > userThumb
macro stylingA simple invite system would make us less concerned by security issues, because we'd have trusted members only. The process:
How it would work:
Not super safe, but simple enough.
Note: plenty of code can be reused from the Sessions service
Replace all uuid
-based URLs with name
-based ones. It involves:
entryController.js#saveEntry
(without worrying about name-clashing for now).controllers/templating.js#buildUrl()
functionTip: updating the samples in core/db.js#insertSamples()
to test stuff will be useful.
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(?).
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.
Requires #63
Use https://github.com/mpneuried/nodecache (integrated to core/cache.js
during #52) to cache simple things (trace SQL calls to find relevant candidates) like:
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).
Skim through the code and check the following things:
Other tasks:
(*) Right now the amount of SQL queries per request is not pretty:
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" = ?' }
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" = ?' }
Will be used at least for password recovery.
Fields entry.is_mod and entry.is_admin
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.