taylortom / adapt-authoring Goto Github PK
View Code? Open in Web Editor NEWA server-based user interface for authoring eLearning courses using the Adapt framework.
Home Page: http://adaptlearning.org
A server-based user interface for authoring eLearning courses using the Adapt framework.
Home Page: http://adaptlearning.org
See Code etiquette page for a starting point.
There's currently no mechanism to document the external API endpoints.
i.e. should it be possible to connect to multiple mongo instances in a single app.
Original isn't actively maintained, so may be better to switch to one of the forks:
See this Google Doc for more notes.
Below list is subject to change once discussed.
Does it matter where the auth comes in the stack (i.e. should other middleware be able to run before auth middleware)
Probably not, but for performance reasons it would be good to be able to stop any unnecessary middleware running if user doesn't have access to the system.
Think it'd be good to encapsulate the install/upgrade process in a separate module to allow for easy modification/replacement later. This would also allow for easier testing + interaction between the installer and other parts of the application.
If the installer is an Adapt Module, it'd also be easy to replicate the version check + log output that we have currently.
Original problem here was that any errors occurring before logger has initialised use console log & were therefore ugly. I've refactored this so that the logging works as expected, but it needs another rewrite as feels a bit hacky.
What we need:
In the current incarnation, courseasset
records are used to flag individual asset instances.
Possible solutions:
See /bin/cli.js#L85
Would be nice to specify the config for a module in the config/package.json
for the module, with a default option if not configured.
Example:
mongodb
as storagegoogleanalytics
as its storageModule#storage
function gets the storage module according to the module's config:
mongodb
for usersgoogleanalytics
for analyticsConsidering that writing APIs will be the main task when extending the authoring tool, we could do with writing some reusable bits to make API creation less code-heavy (and remove duplication).
Things you want to define when creating an API:
Other points:
POST
, GET
, UPDATE
, DELETE
POST
requests have a body)controller.js
, api.js
etc.), so you can omit boilerplate loading code if using these standard pathspackage.json
...and probably schema)Main requirement with this is to be able to allow modules to interact with key parts of the application without needing to know about the implementation.
Main areas I'm thinking of with this:
Requirements:
We need to think about how unit tests will be implemented and run.
See https://github.com/taylortom/adapt-authoring-server/blob/master/lib/module.js#L54
On a related note: should we expose the express app to allow for direct access to the express Application? Might be useful.
We need a module to allow storage to both local and remote sources (by default, we only need to support local file storage).
Would be nice to allow the following:
Possible API example:
await filestore.writeFile('http://drive.google.com/myFile.txt', 'googledrive');
const file = await filestore.readFile('http://drive.google.com/myFile.txt', 'googledrive');
// no param defaults to config 'defaultStore' option or similar
const file = await filestore.readFile('/path/to/myFile.txt');
Allow easy user configuration with as little input from the user as possible.
if(!configValue) ...
).config.mongodb.server_port
)
process.env
, so make sure this is read once and cachedFor consistency, these should mirror the format we use for other schemas throughout the app.
Allow devs to include schemas with any modules which allow them to specify what config options are needed, and what values are acceptable:
These schemas could then be processed during the app boot process to:
Schemas would also be useful for various automated processes:
config/config.json
route requires a hard-coded list of whitelisted attributes, schemas could expose a value which would set this (e.g. hidden
)config/config.json
API route.Might be nice to be able to 'register' errors to the app, to allow easy error type reuse across all modules in the app.
Note: not saying the below is the best way to implement, but gets my point across
e.g. Say a HelloWorld module defines a HelloWorldError:
class HelloWorld {
constructor() {
this.app.registerError(HelloWorldError);
}
}
Some OtherModule can then use this error like so:
class OtherModule {
someFunc() {
throw this.app.ErrorFactory('HellowWorldError', { option: 1, option: 'two' });
}
}
If the specific error hasn't been defined, a standard Error can be returned.
Can parse the schemas to generate this.
This issue covers the basic implementation of authentication.
Maybe Router._expressRouter
Think it's useful to have this secretly accessible in case you need access to any Express API not surfaced by the AAT code.
List of modules that are needed for the restructure. These will be a mixture of the existing /lib
and /plugins
files, as well as some necessary extras now we're using a modular architecture.
'Module' column refers to whether the module is an Adapt authoring module (rather than just a standard Node module).
To be called in Module constructor.
Some questions:
this.app.lang.t
, this.app.logger.log
) -- would nice to add dev-friendly shortcuts to these functions (e.g. this.t
, this.log
), but how does this fit into the above?This is likely to be a particular problem with the unit tests. The most common example being the lang module (and translating error strings etc.) - should the app continue to function if this isn't present (we can obviously mock the translation module to get around this in tests).
...to check required data exists, and that it's safe.
Note: we can't check req.params
until the request passes through the router that defines them.
For reference: Middleware#sanitiseInput
The middleware nullifies body/params/query on the request if they're empty objects. The original intention was to make presence checking a bit cleaner by using truthy values (e.g. if(req.body) {}
rather than checking keys etc. each time).
HOWEVER, this now leads to extra defensive code if you need to use properties of the above (e.g. if(req.params && req.params._id) {}
which is annoying...).
Possible solutions:
req.hasBody
, req.hasParams
etc.)e.g.
Person.
find({ occupation: /host/ }).
where('name.last').equals('Ghost').
where('age').gt(17).lt(66).
where('likes').in(['vaporizing', 'talking']).
limit(10).
sort('-occupation').
select('name occupation').
exec(callback);
It would be nice to be able to update the list of local dependencies and still be able to update via git without losing the local changes (as would happen if package.json was edited). Any solution needs to make sure npm install
etc. still work as expected.
Need to highlight required somehow
Write a core module specification/definition guide for developers. This should be used in conjunction with #28.
Things to include:
Spec:
Input isn't currently validated prior to adding it to the routes list. We should probably add something here to check the route has the required structure.
I'm starting to think this is an abstraction for abstraction's sake; not sure it's really useful in the long-run. Is it useful to have a query class that can be used for all 3? Queries to different datastores are probably going to vary enough to make render this a bit pointless. It's also probably a bit more dev-friendly + transparent to expose datastore-specific APIs.
Example DataStores
Probably makes sense to base module around Polyglot.js again
Very generic one, but I've not done a lot of async/await in the current prototype, so could do with identifying any areas that would be a good use of it.
Would be nice to be able to include generic docs which don't necessarily fit with a specific module here (e.g. installation steps).
It might be useful to include middleware in a central 'pool' so they can be reused by other modules.
Assuming two modules are on the same server, it's overkill to have to create http requests to use functionality across each module. What is the best way to bridge this gap?
Requirements:
Possible solutions:
From npmjs.com:
bcrypt-nodejs is no longer actively maintained. Please use bcrypt or bcryptjs. See https://github.com/kelektiv/node.bcrypt.js/wiki/bcrypt-vs-brypt.js to learn more about these two options
bcrypt (285k weekly D/Ls, updated 14/04/19)
C++, faster, non-blocking.
bcryptjs (446k weekly D/Ls, updated 04/01//17)
Pure JS, slower, blocking.
Leaning towards bcryptjs because of the hit on install of the native stuff.
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.