Application Architecture - abought/osf.io GitHub Wiki

Application Architecture

Overall Concepts

The URL structure of the application components should be reflected in the organization of the codebase. That said, it need not be a 1:1 correspondence. For instances - while both authentication and user profile will be exposed through the /user/ URL, they should be discrete modules -./user/authentication/ and ./user/profile/ respectively.

The OSF blog should be hosted on a subdomain (blog.openscienceframework.org), and is not considered here.

URL structure

/user/<id>/profile/

User profiles.

NOTE: /profile/<id> is the current location. I'd like to move it, but of course continue to support the legacy location through redirection. I'd like to keep URIs "guessable", in that attributes of the user should be on that user's URI path. For example - user x's profile should be at /user/x/profile, their dashboard at /user/x/dashboard, and a list of their projects at /user/x/projects/. Their activity feed (RSS) should be at /user/x/activity/.

/project/<id>

Canonical link to projects.

/pages/<id>

"Flat" pages - those that are not dynamically generated for each call. This lets us get things like "FAQs" and "About" out of the root namespace.

/admin/*

Code Structure

/

File Contains
main.py import site app factory; create app; dev server

/modules/

Top-level folder for modules that are either brought into the project from projects spawned by COS, or are destined to be spun off of the OSF into their own projects.

This should considered be a temporary state - packages should eventually be pushed to PyPI, and can then be installed using pip as part of the Python environment. We don't need to be including the source bodily in the OSF codebase long-term. As an intermediate step, pip can install a branch of a Github repo.

/site/

Code that is specific to the OSF should be here, and every effort should be made to make this as minimal and clean as possible.

File Contains
__init__.py app factory for Flask; wireup of URL routing
settings.py site setting defaults, overrides for env vars

/site/core/

File Contains
__init__.py

models.py

Base classes, like Node - these should not be used directly, but subclassed: e.g., Project, Component

/site/components/ -------------------

File Contains
__init__.py Wires up routes to Flask Blueprint object.

views.py

Views for use with the Project model. These include the project dashboard, add project page, etc. Views relating to components should be imported here as well, and a Flask Blueprint defined.

models.py

Includes Project, Registration and Component - plus their parent class, Node.

  • Project

    • Top-level object - has no ancestors.
    • Has a category attribute, which is always "project"
  • Registration

    • Is Read-only
    • Has a category attribute, which is always "registration"
    • For implementation, is a subclass of Node - with all methods that would modify the object overwritten to raise an exception.
  • Component

    • Child of a Project
    • Has access permissions. In the future, should be able to have its own permission set, or inherit from its parent.
    • Has a user-defined category attribute

/site/components/pieces/

File Contains
__init__.py

models.py

Defines models used as children of components. Examples: File, Log, WikiPage

views.py

Views exposable to select or act upon components. URL routes do not go here.

While there are models and views here, they depend upon other objects for semantic context. A Log, by itself, is meaningless - what was the logged event referencing?

Because of this, there is no routing at this level. Instead, the views exposed here should be routed at the level of the objects they reference.

/site/components/templates/ -----------------------------

Partial templates to render projects and components. These should be able to be overridden by templates in the site's top-level directory, but should not be in our application. The idea is that if another project wants to use our structure of Node > Project > (WikiPage | Log | File | Hypothesis | etc.), they can do so without starting from scratch.

/site/templating/

Everything necessary to render Mako templates for the site.

File Contains
__init__.py creation of Mako environment
dates.py helpers for date handling

/site/user/

This will contain no files, unless we need to (for instance) subclass User to override a generic profile attribute with the one specific for this site -or to provide one for submodules to use.

/site/user/authentication

Handle password hashing and salting, verify user identity. Password recovery. Third party authentication goes here, too.

/site/user/registration

Handle registration flow. This could include emailing the user, verifying the key upon confirmation.

/site/user/profile

Metadata associated with the user's account.

/templates/

All templates should go here, including those that are not used to render HTML.

As the file extension for templates are effectively arbitrary to the renderer, they should reflect the type of content they render.

Subdirectories here should mirror the URL structure as closely as possible. ./templates/_partials/ should contain child templates that are used in many locations across the site.

No Python should exist in this directory, nor should it be a module.

⚠️ **GitHub.com Fallback** ⚠️