NAME
    App::MFILE::WWW - Web UI development toolkit with prototype demo app

VERSION
    Version 0.136

LICENSE
    This software is distributed under the "BSD 3-Clause" license, the text
    of which can be found in the file named `COPYING' in the top-level
    distro directory. The license text is also reprodued at the top of each
    source file.

SYNOPSIS
        $ man mfile-www
        $ mfile-www
        $ firefox http://localhost:5001

DESCRIPTION
    This distro contains a foundation/framework/toolkit for developing the
    "front end" portion of web applications.

    App::MFILE::WWW is a Plack application that provides a HTTP
    request-response handler (based on Web::Machine), CSS and HTML source
    code for an in-browser "screen", and JavaScript code for displaying
    various "widgets" (menus, forms, etc.) in that screen and for processing
    user input from within those widgets.

    In addition, infrastructure is included (but need not be used) for user
    authentication, session management, and communication with a backend
    server via AJAX calls.

    Front ends built with App::MFILE::WWW will typicaly be menu-driven,
    consisting exclusively of fixed-width Unicode text, and capable of being
    controlled from the keyboard, without the use of a mouse. The overall
    look-and-feel is reminiscent of the text terminal era.

    The distro comes with a prototype (demo) application to illustrate how
    the various widgets are used.

QUICK START (DEMO)
    App::MFILE::WWW can be run as a standalone HTTP server providing a
    self-contained demo application.

    Assuming App::MFILE::WWW has been installed properly, this mode of
    operation can be started by running `mfile-www', as a normal user (even
    'nobody'), with no arguments or options:

        $ mfile-www

    The start-up script will write information about its state to the
    standard output. This includes the location of its log file, the port
    where the HTTP server is listening (default is 5001), etc. For a
    detailed description of what happens when the start-up script is run,
    see the POD of `mfile-www' itself - e.g. "man mfile-www".

WRITING A DERIVED CLIENT
    Now that you have the demo running, you probably want to roll up your
    sleeves and start using this to write your own application. Now is a
    good time to read about the basic architecture of applications based on
    App::MFILE::WWW.

  Stack
    The full stack, of which App::MFILE::WWW is a part, consists of the
    following components:

    * Database engine
        For storing application data.

    * Perl DBI
        For interfacing between the Perl code and the database engine.

    * REST server
        A REST server, such as App::Dochazka::REST, implements a data model
        and provides an HTTP interface to that model.

    * optional CLI client/frontend
        An optional Command Line Interface (frontend) can provide a command
        line interface to the REST server.

    * WWW client/frontend
        The WWW frontend, built from this distro, is a web server that
        serves HTML, CSS, and JavaScript code to users to provide them with
        a menu-driven "browser experience" of the application.

    Conceptually, the frontends (or "clients") act as proxies between the
    user and the REST server in this setup. Taking this one step further,
    the REST server itself is a proxy between the client and the database
    engine.

    Strict separation between backend (REST server) and frontend (clients)
    is a technical measure that makes the application as a whole more
    robust.

DERIVED WWW CLIENTS
    When you write your own web frontend using this distro, from
    App::MFILE::WWW's perspective it is a "derived client" and will be
    reffered to as such in this document.

  Derived client operation
    In a derived-client scenario, App::MFILE::WWW is basically used as a
    library, or framework, upon which the "real" application is built.

    The derived-client handling is triggered by providing the `--ddist'
    command-line option, i.e.

        $ mfile-www --ddist=App-Dochazka-WWW

    Where 'App-Dochazka-WWW' refers to the Perl module App::Dochazka::WWW,
    which is assumed to contain the derived client source code.

    So, in the first place it is necessary to create such a Perl module. It
    should have a sharedir configured and present. One such derived client,
    App::Dochazka::WWW, is available on CPAN.

IMPLEMENTATION DETAILS
  HTTP request-response cycle
    The HTTP request-response cycle is implemented as follows:

    * nginx listens for incoming connections on port 80/443 of the server
    * When a connection comes in, nginx decrypts it and forwards it to a
    high-numbered port where a PSGI-compatible HTTP server (such as Starman)
    is listening
    * The HTTP server takes the connection and passes it to the Plack
    middleware. The key middleware component is Plack::Middleware::Session,
    which assigns an ID to the session, stores whatever data the server-side
    code needs to associate with the session, links the session to the
    user's browser via a cookie, and provides the application a hook (in the
    Plack environment stored in the HTTP request) to access the session data
    * if the connection is asking for static content (defined as anything in
    `images/', `css/', or `js/'), that content is served immediately and the
    request doesn't even make it into our Perl code
    * any other path is considered dynamic content and is passed to
    Web::Machine for processing -- Web::Machine implements the HTTP standard
    as a state machine
    * the Web::Machine state machine takes the incoming request and runs it
    through several functions that are overlayed in
    App::MFILE::WWW::Resource - an appropriate HTTP error code is returned
    if the request doesn't make it through the state machine. Along the way,
    log messages are written to the log.
    * as part of the state machine, all incoming requests are subject to
    "authorization" (in the HTTP sense, which actually means
    authentication). First, the session data is examined to determine if the
    request belongs to an existing authorized session. If it doesn't, the
    request is treated as a login/logout attempt -- the session is cleared
    and control passes to the JavaScript side, which, lacking a currentUser
    object, displays the login dialog.
    * once an authorized session is established, there are two types of
    requests: GET and POST
    * incoming GET requests happen whenever the page is reloaded - in an
    authorized session, this causes the main menu to be displayed, but all
    static content (CSS and JavaScript modules) are reloaded for a "clean
    slate", as if the user had just logged in.
    * Note that App::MFILE::WWW pays no attention to the URI - if the user
    enters a path (e.g. http://mfile.site/some/bogus/path), this will be
    treated like any other page (re)load and the path is simply ignored.
    * if the session is expired or invalid, any incoming GET request will
    cause the login dialog to be displayed.
    * well-formed POST requests are assumed to be AJAX calls and are
    directed to the `process_post' routine, which first examines the request
    body, which must adhere to a simple structure:
            { method: "GET", path: "employee/current", body: { ... } }

        where 'method' is any HTTP method accepted by the REST server,
        'path' is a valid path to a REST server resource, and 'body' is the
        content body to be sent in the HTTP request to the REST server.
        Provided the request is properly authorized and the body is
        well-formed, the request is forwarded to the REST server via the
        App::MFILE package's `rest_req' routine and the REST server's
        response is sent back to the user's browser, where it is processed
        by the JavaScript code.

    * under ordinary operation, the user will spend 99% of her time
    interacting with the JavaScript code running in her browser, which will
    communicate asynchronously as needed with the REST server via AJAX
    calls.

DEVELOPMENT NOTES
    The App::MFILE::WWW codebase has two parts, or "sides": the "Perl side"
    and the "JavaScript side". Control passes from the Perl side to the
    JavaScript side

    * synchronously whenever the user (re)loads the page
    * asynchronously whenever the user triggers an AJAX call

    JavaScript side
    Modular (RequireJS)
    The JavaScript code is modular. Each code module has its own file and
    modules are loaded asynchronously by RequireJS.

    Unit testing (QUnit)
    The JavaScript code included in this package is set up for unit testing
    using the QUnit http://qunitjs.com/ library.

    UTF-8
    In conformance with the JSON standard, all data passing to and from the
    server are assumed to be encoded in UTF-8. Users who need to use
    non-ASCII characters should check their browser's settings.

  Deployment
    To minimize latency, App::MFILE::WWW can be deployed on the same server
    as the back-end (e.g. App::Dochazka::REST), but this is not required.

PACKAGE VARIABLES
    For convenience, the following variables are declared with package
    scope:

FUNCTIONS
  init
    Initialization routine - run from `bin/mfile-www', the server startup
    script. This routine loads configuration parameters from files in the
    distro and site configuration directories, and sets up logging.

